【问题标题】:Django model custom save with ManyToManyField problem带有ManyToManyField问题的Django模型自定义保存
【发布时间】:2010-10-31 19:02:59
【问题描述】:

我知道这个问题已被多次发布,但我仍然找不到这个问题的明确答案。所以,我开始了:

class Invoice(models.Model):
    program = models.ForeignKey(Program)
    customer = models.ForeignKey(Customer, related_name='invoices')
    participants = models.ManyToManyField(Participant, related_name='participants_set')
    subtotal = models.DecimalField(max_digits=10, decimal_places=2, default='0.00', blank=True, null=False)
    pst = models.DecimalField("PST", max_digits=10, decimal_places=2, default='0.00', blank=True, null=False)
    gst = models.DecimalField("GST", max_digits=10, decimal_places=2, default='0.00', blank=True, null=False)
    total = models.DecimalField(max_digits=10, decimal_places=2, default='0.00', blank=True, null=False)

    def save(self, **kwargs):
        super(Invoice, self).save(**kwargs)
        items = self.participants.count()
        subtotal = Decimal(self.program.fee) * items
        pst = self.program.is_pst and Decimal(PST)*subtotal or Decimal('0.00')
        gst = self.program.is_gst and Decimal(GST)*subtotal or Decimal('0.00')
        total = (subtotal + pst) + gst
        self.subtotal = subtotal
        self.pst = pst
        self.gst = gst
        self.total = total
        super(Invoice, self).save(**kwargs)

一切正常,除了 self.participants.count() 不起作用。任何想法可能是什么问题。非常感谢任何帮助。

【问题讨论】:

  • 什么版本的 Django?您对 self.participants.count() 的调用应该有效。
  • count 方法是引发异常,还是给出了错误的值?

标签: django model save manytomanyfield


【解决方案1】:
self.participants.all().count()

【讨论】:

    【解决方案2】:

    我建议使用pre-save signal,而不是覆盖保存方法。除了让你的代码更简洁之外,它还有助于避免像这样的奇怪问题:)

    【讨论】:

      【解决方案3】:

      我认为发生的事情是因为您在保存期间尝试了参与者计数,查询可能无法找到所有内容。如果您在创建数据库时依赖此数字,我认为不会正确同步多对多表,因为 Invoice 尚未分配 ID。

      相反,其他参与者可能不会保存到数据库中。无论哪种方式,无论使用信号如何,在保存期间取决于此数字都将不起作用。我建议使用单独的方法来执行此计算。它更干净,提高了保存性能,并且您可以在不保存的情况下调用它。

      【讨论】:

      • 将参与者完全分开并只记录数量(参与者的数量)听起来是个好主意。这样 Invoice 模型会更通用。
      【解决方案4】:

      我遇到了类似的问题。我有一个支持 del.icio.us 样式标签的模型。保存函数将解析标签列表(例如“python django web”)并通过调用帮助函数 update_tags() 将它们转换为单独的标签对象实例(参见下面的简化示例)。但是,当我在管理界面中编辑对象时,ManyToManyField 不会反映更改。

      class Article(models.Model):
          tag_string = models.CharField(max_length=255, null=True, blank=True) #del.icio.us style tags, like: django python software
          tags =  models.ManyToManyField(Tag, blank=True)
      
          def save(self, force_insert=False, force_update=False):
              super(Article, self).save(force_insert, force_update)
      
              self.update_tags() #The result of this function didn't seem to be saved in the ManyToManyField
      

      事实证明,管理界面覆盖了对 ManyToManyField 的更改。解决方案只是从 admin.ModelAdmin 中删除 ManyToManyField:

      class ArticleAdmin(admin.ModelAdmin):
          exclude = ['tags']
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-11
        • 2023-03-10
        • 2020-11-15
        • 1970-01-01
        • 2020-02-02
        • 1970-01-01
        • 2014-07-11
        • 2019-10-18
        相关资源
        最近更新 更多