【问题标题】:Django set model fields after createDjango 在创建后设置模型字段
【发布时间】:2019-06-08 23:38:20
【问题描述】:

我有一个模型电影和一个模型 DefaultMoviePriceFor,它保存了特定类型的默认价格:

class Movie(models.Model):
    name = models.TextField('name', null=True)
    genre = models.TextField('genre', null=True)
    price = models.IntegerField('price', default=0)

class DefaultMoviePriceForGenre(models.Model):
    genre = models.TextField('genre', null=True)
    price = models.IntegerField('price', default=0)

现在我想在每次实例化 Movie 对象时用 Movie.genre 的默认价格填充 Movie.price。

有什么好的方法吗?我脑子里有 SQL 触发器,他们可以做到,不是吗?在django中是怎么做的?

【问题讨论】:

  • 使price 可以为空,如果它为空,则获取相关的DefaultMoviePriceForGenre
  • @WillemVanOnsem 但在哪里?模型实例化时是否调用了任何方法?
  • 与问题的“如何在保存时调用自定义代码”部分无关 - 如果您也将 genre 设为模型并使用 ForeignKey 关系来确保数据正确一致。

标签: python django django-models


【解决方案1】:

一种方法是使用pre-save signal。这将在模型的任何实例被保存之前立即触发,并会收到一个 created 布尔参数,仅当对象是新对象时才允许您设置价格。

如果出于某种原因您想在保存后执行此操作,还有一个保存后信号,例如,因为您的行为取决于新实例的 PK。但是预保存在这里应该可以工作。

或者,您可以覆盖模型类的save 方法。 https://docs.djangoproject.com/en/2.1/topics/db/models/#overriding-model-methods

有关这两种方法的优缺点的一些讨论,请参阅此答案:Django signals vs. overriding save method

这一切都假设所需的行为与描述的完全一样 - 在创建实例时查找该类型的当前默认价格,并独立于未来对该类型的更改进行保存。如果你想做一些更灵活的事情 - 例如说“恐怖电影现在成本 X 除非被覆盖,但如果我稍后更改默认类型价格,它们应该都更新”你可能最好使用 Movie 类上的方法来计算价格基于当前状态,而不是在创建时设置并断开该连接。但这取决于你想要什么。

【讨论】:

    猜你喜欢
    • 2015-03-06
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 2016-11-04
    • 2015-04-16
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    相关资源
    最近更新 更多