为什么不django的model.save()调用full_clean()?
我只是好奇,如果有人知道为什么django的orm不会在模型上调用“full_clean”,除非它被保存为模型表单的一部分。
请注意,调用模型的save()方法时,不会自动调用full_clean()。 当您想要为自己手动创build的模型运行一步模型validation时,您需要手动调用它。 django的完整清洁文档
(注意:引用更新为Django 1.6 …以前的django文档也有关于ModelForms的警告。)
人们不希望这种行为有充分的理由吗? 我认为如果你花时间为模型添加validation,那么每次保存模型时都要运行validation。
我知道如何让一切正常工作,我只是在寻找一个解释。
AFAIK,这是因为向后兼容。 带有排除字段的模型,带缺省值的模型,pre_save()信号等也有问题。
您可能感兴趣的来源:
由于考虑到兼容性,django内核没有启用自动清理保存。
如果我们正在启动一个新项目,并希望Model上的默认save
方法可以自动清理,我们可以在保存每个模型之前使用以下信号进行清理。
from django.dispatch import receiver from django.db.models.signals import pre_save, post_save @receiver(pre_save) def pre_save_handler(sender, instance, *args, **kwargs): instance.full_clean()
调用full_clean
方法的最简单方法就是覆盖model
save
方法:
def save(self, *args, **kwargs): self.full_clean() return super(YourModel, self).save(*args, **kwargs)
我们可以在settings.py
使用INSTALLED_APPS
部分的应用程序,而不是插入一段声明接收器的代码
INSTALLED_APPS = [ # ... 'django_fullclean', # your apps here, ]
在此之前,您可能需要使用PyPI安装django-fullclean
:
pip install django-fullclean
如果你有一个模型,你要确保至less有一个FK关系,并且你不想使用null=False
因为这需要设置一个默认的FK(这将是垃圾数据),我最好的方式来最后是添加自定义.clean()
和.save()
方法。 .clean()
会引发validation错误,而.save()
调用clean。 通过这种方式,完整性可以从表单和其他调用代码,命令行和testing中强制执行。 没有这个,就没有办法写一个testing来确保一个模型与一个特定的(不是默认的)其他模型具有FK关系。
class Payer(models.Model): name = models.CharField(blank=True, max_length=100) # Nullable, but will enforce FK in clean/save: payer_group = models.ForeignKey(PayerGroup, null=True, blank=True,) def clean(self): # Ensure every Payer is in a PayerGroup (but only via forms) if not self.payer_group: raise ValidationError( {'payer_group': 'Each Payer must belong to a PayerGroup.'}) def save(self, *args, **kwargs): self.full_clean() return super().save(*args, **kwargs) def __str__(self): return self.name