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

发布于 2024-07-23 11:33:03 字数 1324 浏览 2 评论 0原文

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

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

I know this question has been posted multiple times but I still couldn't find a definite answer to this problem. So, here I go:

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)

Everything works fine except self.participants.count() doesn't work. Any idea what could be the problem. Any help much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

独守阴晴ぅ圆缺 2024-07-30 11:33:03
self.participants.all().count()
self.participants.all().count()
野心澎湃 2024-07-30 11:33:03

我建议使用 预保存信号。 除了让你的代码更简洁之外,它还有助于避免像这样的奇怪问题:)

Instead of overriding the save method, I'd recommend using the pre-save signal. Besides making your code a bit cleaner, it helps avoid strange issues like these :)

此岸叶落 2024-07-30 11:33:03

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

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

I think what's happening is because you are trying a participants count during a save, the query may not be finding everything. If you're depending on this number at database creation time, I don't think the many-to-many table will be synced up correctly because the Invoice doesn't have an ID assigned yet.

Conversely, the other participants may not be saved to the database. Either way, depending on this number during a save won't work, regardless of using signals. I would recommend having a separate method that does this computation. It's cleaner, it improves save performance, and you can call it without saving.

以可爱出名 2024-07-30 11:33:03

我有类似的问题。 我有一个支持 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']

I had a similar problem. I had a model that supported del.icio.us style tags. The save function would parse a list of the tags (e.g. "python django web") and convert them into individual tag object instances by calling a helper function update_tags() (see below for a simplified example). However, the ManyToManyField would not reflect the changes when I edited the object within the admin interface.

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

It turns out that the admin interface was overriding the changes to the ManyToManyField. The solution was simply to remove the ManyToManyField from the admin.ModelAdmin:

class ArticleAdmin(admin.ModelAdmin):
    exclude = ['tags']
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文