【发布时间】:2017-04-25 14:12:52
【问题描述】:
如果一个有两个模型:
class Invoice(models.Model):
class Meta:
ordering = ('-date_added', )
number = models.CharField(max_length=10,)
comments = models.TextField(blank=True, help_text="Notes about this invoice." )
total = models.DecimalField(max_digits=9, decimal_places=2, default="0" )
date_added = models.DateTimeField(_('date added'), auto_now_add=True)
date_modified = models.DateTimeField(_('date modified'), auto_now=True)
def __unicode__(self):
return "%s: total %s" % (self.number, self.total)
class Part(models.Model):
for_invoice = models.ForeignKey(Invoice)
description = models.CharField(max_length=200, blank=True, help_text=_("Briefly describe the part.") )
supplier = models.CharField(max_length=100, blank=True, help_text=_("Supplier Name.") )
supplier_number = models.CharField(max_length=100, blank=False, help_text=_("Supplier's order number.") )
qty = models.DecimalField(max_digits=3, decimal_places=0, blank=False, null=False, help_text=_("How many are needed?") )
cost = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True, help_text=_("Price paid per unit") )
line_total = models.DecimalField(max_digits=9, decimal_places=2, default="0")
date_added = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
def __unicode__(self):
return "%s: total %s" % (self.for_invoice, self.line_total)
我看到的第一个选择是可以将“line_total”或“total”实现为计算模型字段。但是,如果您这样做,那么您将永远无法按“line_total”或“total”对更改列表进行排序,而用户希望能够这样做。所以我把它们做成模型上的一个保存字段。
阅读 Django 1.10 文档,我看到 4 个地方可以定义代码来计算和更新“total”和“line_total”字段:
- ModelAdmin.save_model(request, obj, form, change) 和 ModelAdmin.save_formset(request, form, formset, change)
- ModelAdmin.save_related(请求、表单、表单集、更改)
- model.save(self, *args, **kwargs))
- 保存信号
在我看来,保存信号的级别太低 - 与单个模型保存事件相关联,它永远无法访问请求或会话。所以把所有的“Part”记录都收集起来会很“烦人”吗?
同样,model.save 方法似乎也过于细化。如果我可以使用 Invoice.save 方法将是“方便的”,因为它可以通过 Invoice.part_set.all() 轻松访问所有相关部分,循环遍历该查询集将是更新 line_total 的一种简单方法,然后是主全部的。但是,此时是否会保存所有新的/更改的零件记录?而且它无法访问 HttpRequest。
我认为这同样适用于管理员的 save_model。但是,我有一个模糊的记忆,可以确保先保存相关部分。我在 Admin 的 Invoice 添加/编辑页面上使用内联列出了这些部分。
我刚刚在 ModelAdmin.save_related 中添加了!我忘了那个。由于此时将保存主发票,也许这是更新所有 Part 记录,然后更新父总计的最佳位置?
提前致谢!
【问题讨论】:
-
您可以按计算字段排序。见this answer。