Django模型自定义保存与ManyToManyField问题

时间:2009-06-05 21:52:06

标签: django model save manytomanyfield

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

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()不起作用。知道可能是什么问题。任何帮助非常感谢。

4 个答案:

答案 0 :(得分:5)

self.participants.all().count()

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

相反,其他参与者可能无法保存到数据库中。无论哪种方式,在保存期间取决于此数字将无效,无论使用信号。我建议有一个单独的方法来执行此计算。它更干净,它提高了保存性能,您可以不用保存就调用它。

答案 3 :(得分:0)

我有类似的问题。我有一个支持del.icio.us样式标签的模型。 save函数将解析标记列表(例如“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']