shy*_*ent 59 python django django-models
模型字段的验证应该在哪里进行django?
我可以命名至少两个可能的选择:在模型的重载.save()方法或models.Field子类的.to_python()方法中(显然,为了工作,你必须编写自定义字段).
可能的用例:
empty_strings_allowedmodels.Field基类定义和派生类中还有一个类级别属性,它可以很好地覆盖它,但它似乎不会对数据库级别产生任何影响,这意味着我仍然可以使用空字符串字段构建模型并将其保存到数据库中.我想避免(是的,这是必要的).
可能的实现是
在现场一级:
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)
Run Code Online (Sandbox Code Playgroud)
在模型级别:
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)
Run Code Online (Sandbox Code Playgroud)
也许,我错过了一些东西,这可以做得更容易(也更清洁)?
Car*_*yer 63
自版本1.2以来,Django已经建立了模型验证系统.
在评论中sebpiq说"好的,现在有一个地方可以进行模型验证......除了它只在使用ModelForm时运行!所以问题仍然存在,当有必要确保在db级别遵守验证时你应该怎么做?在哪里打电话给full_clean?"
通过Python级验证无法确保在数据库级别上遵守验证.最接近的可能是调用full_clean重写save方法.默认情况下不会这样做,因为这意味着调用save方法的每个人现在都可以更好地捕获和处理ValidationError.
但即使你这样做,有人仍然可以使用批量更新模型实例queryset.update(),这将绕过此验证.Django无法实现一个合理有效的方法queryset.update(),它仍然可以对每个更新的对象执行Python级别的验证.
真正保证数据库级完整性的唯一方法是通过数据库级约束; 通过ORM进行的任何验证都要求应用程序代码的编写者了解何时强制执行验证(并处理验证失败).
这就是默认情况下仅强制执行模型验证的原因ModelForm- 因为在ModelForm中已经有一种明显的方法来处理ValidationError.
我想你想要这个 - >
from django.db.models.signals import pre_save
def validate_model(sender, **kwargs):
if 'raw' in kwargs and not kwargs['raw']:
kwargs['instance'].full_clean()
pre_save.connect(validate_model, dispatch_uid='validate_models')
Run Code Online (Sandbox Code Playgroud)
(复制自http://djangosnippets.org/snippets/2319/)
| 归档时间: |
|
| 查看次数: |
43131 次 |
| 最近记录: |