I have a Group model:
class Group(models.Model):
leader = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=55)
description = models.TextField()
joined = models.ManyToManyField(User, blank=True)
and I recently added the ability for the leader
to pass over their leadership to a different User. This is fine, but then I noticed that I had a created by {{group.leader}
at the top of my GroupDetail template, and I figured it would be better to have a founder
and a leader
that way people can see which User founded the Group vs. who is currently leading it.
Now what I'm struggling with is how to implement this. I assume the founder
will be correlated with one User and also with the first leader
of the Group. At one point both fields will be the same User. But how do I have two ForeignKeys in the same model? Or is there a better way to go about this.
As of now the logic to switch leaders is as such:
<form method="POST">
{% csrf_token %}
{{form.as_p}}
<select id="newLeaderSelect">
{% for member in group.joined.all %}
{% if member != group.leader%}
<option id='newLeader' value={{ member.id }}>{{ member }}</option>
{% endif %}
{% endfor %}
</select>
<button>CHANGE LEADER</button>
{{form.errors}}
</form>
<script>
let leader = document.getElementById('leader')
let newLeaderSelect = document.getElementById('newLeaderSelect')
leader.value = newLeaderSelect.value
newLeaderSelect.onchange = () => {
leader.value = newLeaderSelect.value
}
</script>
and my view:
class ChangeLeader(UpdateView):
model = Group
form_class = ChangeLeaderForm
template_name = 'change_leader.html'
def form_valid(self, form):
return HttpResponseRedirect(reverse('group_detail', args=[str(group.pk)]))
Everything works to change the leader so my only question is how do I implement a founder
into my Group model? What's the best way to go about it?
CodePudding user response:
You can have two ForeignKey fields to the same model, it's just your logic that needs to handle how the created_by
field gets updated. A post-save signal would be pretty easy to implement, it also has a Boolean for whether the instance was just created:
class Group(models.Model):
leader = models.ForeignKey(User, ...
created_by = models.ForeignKey(User, ...
...
@receiver(post_save, sender=Group)
def set_created_by(sender, instance, created, **kwargs):
if created:
self.created_by = self.leader
self.save()
CodePudding user response:
I think your idea to have another foreignkey that points to founder is good but if you want to have your group after founder deleted (for any reason) you have to set on_delete to set_null
founder = models.ForeignKey(User, on_delete=models.SET_NULL, null = True)
you can handle logic of saving in save method of your model if you are using default id of model
def save(self,*args, **kwargs):
if self.pk == None:
self.founder_id = self.leader_id
return super().save(*args, **kwargs)
if you are using default pk(id) then if self.pk is None it means that you are inserting