#django #django-models
#django #django-модели
Вопрос:
Я пытаюсь вычислять поле раундов в модели ниже каждый раз, когда создается новый турнир, но для этого мне сначала нужно количество участвующих игроков:
class Tournament(models.Model):
rounds = models.PositiveIntegerField()
players = models.ManyToManyField(User)
def save(self, *args, **kwargs):
self.rounds = self.players.count() 3
super(Tournament, self).save()
Проблемы, по-видимому, заключаются в том, что если super не сохранен, вы не можете получить доступ к его полю m2m:
Экземпляр ‘Tournament’ должен иметь значение первичного ключа, прежде чем можно будет использовать отношение «многие ко многим».
Есть предложения?
_
Я уже тестировал
def save(self, *args, **kwargs):
super(Tournament, self).save()
self.rounds = self.players.count() 3
super(Tournament, self).save()
но players.count() всегда возвращает 0.
сигнал * post_save * был еще одной моей попыткой, но я получил прекрасную бесконечную рекурсию
def trigger_create_round(sender, **kwargs):
tournament = kwargs['instance']
tournament.rounds = tournament.players.count() 3
tournament.save()
post_save.connect(trigger_create_round, sender=Tournament, weak=False)
Спасибо 😉
Редактировать:
Даже при использовании сигнала m2m_changed проблема сохраняется:
def trigger_create_round(sender, instance, action, reverse, model, pk_set, **kwargs):
if action == 'post_add':
for val in pk_set:
print val
m2m_changed.connect(trigger_create_round, sender=Tournament.players.through, weak=False)
но значения не печатаются, хотя были добавлены новые проигрыватели.
Примечание: Я выполняю все управление турнирами через веб-сайт администратора.
Комментарии:
1.
if tournament.rounds != tournament.players.count() 3: tournament.save()
Просто мысль разорвать цикл. вероятно, это лучший способ.2. Отношения «Многие ко многим» сохраняются после сохранения самой модели. Вот почему у вас нет доступа к count из
save
метода модели. Это сделано таким образом, потому что вы не можете сохранить связь «многие ко многим», не имея первичного ключа для модели, и если это окажется новым объектом, у него еще не будет первичного ключа.
Ответ №1:
Я думаю, что ключевым моментом здесь является запуск при сохранении не модели, а m2m. К счастью, для этого есть сигнал: m2m_changed
. instance
Параметром этого сигнала является экземпляр модели (здесь, экземпляр Tournament), который изменяется.
Комментарии:
1. Даже при использовании сигнала m2m_changed проблема сохраняется. Пожалуйста, посмотрите правку в исходном сообщении.