Django模型字段验证

18 浏览
0 Comments

Django模型字段验证

在Django中,模型字段的验证应该放在哪里?

我至少可以提出两种可能的选择:在模型的重载.save()方法中或者在models.Field子类的.to_python()方法中(显然,为了使其工作,您必须编写自定义字段)。

可能的用例:

  • 当绝对需要确保空字符串不被写入数据库时(blank=False关键字参数在这里不起作用,它仅用于表单验证)
  • 当需要确保在数据库级别上尊重“choices”关键字参数而不仅仅在管理界面上尊重时(类似于模拟枚举数据类型)

模型字段基类定义中还有一个类级属性empty_strings_allowed,派生类可以愉快地覆盖它,但是它似乎对数据库级别没有任何影响,这意味着我仍然可以构造一个具有空字符串字段的模型并将其保存到数据库中。我想避免这种情况(是的,这是必要的)。

可能的实现方式有:

在字段级别上:

class CustomField(models.CharField):
    __metaclass__ = models.SubfieldBase
    def to_python(self, value):
        if not value:
            raise IntegrityError(_('Empty string not allowed'))
        return models.CharField.to_python(self, value)

在模型级别上:

class MyModel(models.Model)
    FIELD1_CHOICES = ['foo', 'bar', 'baz']
    field1 = models.CharField(max_length=255, 
               choices=[(item,item) for item in FIELD1_CHOICES])
    def save(self, force_insert=False, force_update=False):
        if self.field1 not in MyModel.FIELD1_CHOICES:
            raise IntegrityError(_('Invalid value of field1'))
        # this can, of course, be made more generic
        models.Model.save(self, force_insert, force_update)

也许,我漏掉了什么,这可以更简单(和更清晰)地实现?

0