How to add two ForeignKey(User) in django model?

Question:

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?

Asked By: Eddy

||

Answers:

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()
Answered By: 0sVoid

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

Answered By: Mohammadh Rzn