【问题标题】:Autocalculate field in a django model自动计算 django 模型中的字段
【发布时间】:2011-05-10 17:13:54
【问题描述】:

每次创建新锦标赛时,我都会尝试在下面的模型中计算 rounds 字段,但要做到这一点,我首先需要参与的玩家数量:

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' 实例需要有一个 a 之前的主键值 可以使用多对多关系。

有什么建议吗?

_

我已经测试过了

    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)            

但尽管添加了新玩家,但不会打印任何值。

注意:我正在通过管理网站进行所有比赛管理。

【问题讨论】:

  • if tournament.rounds != tournament.players.count() + 3: tournament.save() 只是想打破循环。可能是更好的方法。
  • 模型本身保存后保存多对多关系。这就是为什么您无法从模型的 save 方法中访问计数的原因。这样做是因为如果没有模型的主键就无法保存多对多关系,而且如果它碰巧是一个新对象,它还没有主键。

标签: django django-models


【解决方案1】:

我认为这里的关键不是触发保存模型,而是触发 m2m。幸运的是,有一个信号:m2m_changed。该信号的instance 参数是正在更改的模型实例(此处为锦标赛实例)。

【讨论】:

  • 即使使用 m2m_changed 信号,问题仍然存在。请参阅原帖上的编辑
猜你喜欢
  • 1970-01-01
  • 2018-06-19
  • 2020-08-06
  • 1970-01-01
  • 1970-01-01
  • 2019-09-10
  • 2020-05-19
  • 1970-01-01
  • 2018-03-16
相关资源
最近更新 更多