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?
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()