【问题标题】:What's the verdict? Validation in my model, or in the model form?判决结果是什么?在我的模型中验证,还是在模型表单中验证?
【发布时间】:2015-05-10 11:57:15
【问题描述】:

我知道有人问过这个问题 herehereelsewhere

...但回答似乎有点不确定。我想也许下面的具体例子可能会引起一些具体的原因,说明这是或不是一个好的策略。

那么,这样做有什么问题呢?排除的字段和默认值似乎工作得很好。某些 ORM 方法不会调用 save(),但您也不会利用 ModelForms。还有什么我想念的吗? 只是向后兼容吗?

from django.db import models
from django.core.exceptions import ValidationError

class Person(models.Model):
    favorite_food = models.CharField(max_length=250)

    def clean(self, *args, **kwargs):
        if self.favorite_food == 'bacon':
            raise ValidationError('Bacon is not good for you!')
        super(Person, self).clean(*args, **kwargs)

    def save(self, *args, **kwargs):
        self.full_clean()
        super(Person, self).save(*args, **kwargs)

为了 DRY,“胖模型”,至少将验证放在模型中似乎不是一个好的经验法则吗? ...并且仅将验证逻辑移到 ModelForms 中,其中验证上下文可能取决于模型外部的字段,例如 request.user 的权限? (即便如此,如果这很重要,也许他们应该在模型中?)

我真的很喜欢验证 bacon,在一个地方,而不是这里,在 ModelFrom 和再次在管理员表单中......希望听到一些反对这样做的有力论据!

【问题讨论】:

    标签: python django django-models django-forms


    【解决方案1】:

    这可能会因为太宽泛而被关闭,但我会尽力给出最好的答案,那就是……也许吧。

    Django 模型就是那种模型,所以将其作为数据建模练习而不是作为表单与模型的事情来处理。重要的是要注意Django does provide documentation that actually encourages overriding the `clean* method,在像你这样的情况下。

    但是,在更广泛的意义上,为了回答您的问题,以下是一些可能有助于回答您的问题:

    • 在模型中对这种逻辑建模有意义吗? - 如果您确定 Person 不应该将培根作为最爱,那么在这里建模就不是问题。它是域的一部分,在这里强制执行是“合乎逻辑的”。
    • 逻辑会偶尔改变吗? - 模型(在我看来)应该保持相对静态,它们是您业务领域的抽象 - 希望不会经常改变。如果你发现你的逻辑会经常改变,把它放到你的表单中是一个更好的选择。幸运的是,您可以在主站点和管理站点之间重复使用表单。
    • 逻辑会改变经常吗? - “不可接受”的项目列表会发生很大变化吗?在运行时?非开发人员管理员?现在我们又回到了建模阶段。也许需要有一个模型来管理“不可接受的食品”,并对照该模型进行检查。

    最终,这是否是一个“好策略”是高度主观的,并且取决于您的实际代码,而不仅仅是假的Food 模型*。重写 clean 方法的能力是有原因的,只要你能证明这个位置是正确的,那么你就可以开始了。

    * Not that I have anything against contrived fake examples using food.

    【讨论】:

      猜你喜欢
      • 2011-01-22
      • 2019-05-02
      • 1970-01-01
      • 1970-01-01
      • 2016-07-13
      • 1970-01-01
      • 1970-01-01
      • 2013-08-16
      • 1970-01-01
      相关资源
      最近更新 更多