Как добавить два ForeignKey(User) в модель django?
У меня есть модель группы:
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)
и недавно я добавил возможность для leader
передавать свое лидерство другому пользователю. Это прекрасно, но потом я заметил, что у меня есть created by {{group.leader}
в верхней части шаблона GroupDetail, и я решил, что будет лучше иметь founder
и leader
, чтобы люди могли видеть, какой пользователь основал группу, а кто сейчас ее возглавляет.
Теперь я затрудняюсь с тем, как это реализовать. Я предполагаю, что founder
будет соотноситься с одним пользователем, а также с первым leader
группы. В какой-то момент оба поля будут одним и тем же пользователем. Но как мне иметь два ForeignKeys в одной модели? Или есть лучший способ сделать это
На данный момент логика переключения лидеров такова:
<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>
и мое мнение:
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)]))
Все работает для смены лидера, поэтому мой единственный вопрос - как мне внедрить founder
в мою модель группы? Как лучше всего это сделать?
Вы можете иметь два поля ForeignKey для одной и той же модели, просто ваша логика должна обрабатывать то, как поле created_by
обновляется. Сигнал после сохранения будет довольно легко реализовать, он также имеет булево значение для того, был ли экземпляр только что создан:
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()
Я думаю, что ваша идея иметь другой foreignkey, указывающий на основателя, хороша, но если вы хотите, чтобы ваша группа после удаления основателя (по любой причине) была удалена, вы должны установить on_delete в set_null
founder = models.ForeignKey(User, on_delete=models.SET_NULL, null = True)
Вы можете управлять логикой сохранения в методе сохранения вашей модели, если вы используете идентификатор модели по умолчанию
def save(self,*args, **kwargs):
if self.pk == None:
self.founder_id = self.leader_id
return super().save(*args, **kwargs)
если вы используете pk(id) по умолчанию, то если self.pk равно None, это означает, что вы вставляете