我将什么样的数据传递给Django Model.save()方法?

时间:2010-06-01 05:10:01

标签: python django django-models

假设我们在Django中发布了这样的表格:

rate=10
items= [23,12,31,52,83,34]

项目是Item模型的主键。我有一堆业务逻辑,它将根据这些数据运行并创建更多项目,一些数据库查找的结果和一些业务逻辑。我想将该逻辑放入保存信号或另一个模型的重写Model.save()方法(让我们称之为Inventory)。当我使用此表单数据创建新的Inventory对象时,将运行业务逻辑。库存将如下所示:

class Inventory(models.Model):
    picked_items = models.ManyToManyField(Item, related_name="items_picked_set")
    calculated_items = models.ManyToManyField(Item, related_name="items_calculated_set")
    rate = models.DecimalField()
    ... other fields here ... 

将根据传入的项目创建新的calculated_items,这些项目将存储为picked_items

我的问题是:这个模型上的save()方法更适合接受:

  • 请求对象(我真的不喜欢这种耦合)
  • 表单数据作为参数或kwargs(主键列表和其他表单字段)
  • 项目列表(来电者表单或视图将查找项目列表并创建列表以及传入其他表单字段)
  • 其他一些方法?

我知道这有点主观,但我想知道一般的想法是什么。我查看过很多代码,但是我很难找到自己喜欢的模式。

澄清:

好的,所以共识是它应该在模型上进入不同的功能,例如inventory.calculate(...),然后创建所有内容,执行业务逻辑等......这很有用。我的问题仍然是:将表单数据查找到db对象的最佳位置在哪里?此函数的调用者是否应将主键转换为数据库模型,或者模型方法是否应接受主键并自行执行?这是我想在整个项目范围内做同样的事情。

澄清2:

好的,现在对于覆盖save是否合适存在一些分歧。

当您获得简单CRUD类型操作的表单提交时,您将模型和值作为参数传递给Model.objects.create(...)或覆盖save或使用信号或其他任何内容。

我认为我的问题的核心是:

如果表单提交具有用于业务逻辑的相关模型,那么您需要将一些业务逻辑写入模型层。当你这样做,它应该去哪里,该方法应该接受一个对象列表或一个id的列表?模型API应该接受对象还是id?

1 个答案:

答案 0 :(得分:1)

好的,所以我得到的前两个答案现在已经与其他人相矛盾了。我一直在研究这个问题,我打算自己回答一下。如果您认为这是正确的,请投票和/或如果您不同意我的推理,请发表评论。

  • 模型上的方法应该接受对象和对象列表,而不是id作为int / long或id的列表或类似的东西。这是因为它可能会从视图或表单中调用,并且可以访问cleaned_data dict中的完整对象。管理器类的create()方法是另一个django本身接受对象的例子。

  • 模型图层方法的调用者应查找并将id转换为完整对象。

  • 您可以覆盖save(),但如果这样做,则应小心接受args**kwargs

  • 如果模型跨越应用程序,则应考虑信号而不是覆盖save

  • 不要试图巧妙地覆盖模型管理器create方法。如果视图层创建新对象并保存它,则不会调用它。如果您需要在保存之前执行额外处理,则可以覆盖save__init__或捕获信号。如果覆盖__init__,您可以检查pk以确定它是否存在于数据库中。

我现在要将我的创建代码放在一个单独的方法中,直到找出我最喜欢哪种技术。

我认为这是向模型层添加方法的一套很好的指南。我错过了什么?