我不确定如何在模型的保存方法中正确地引发验证错误并向用户发送一条明确的消息。
基本上,我想知道“if”的每一部分应该如何结束,我想引发错误的部分和它实际保存的部分:
def save(self, *args, **kwargs):
if not good_enough_to_be_saved:
raise ValidationError
else:
super(Model, self).save(*args, **kwargs)
然后我想知道如何发送一个验证错误,准确地告诉用户哪里出了问题,就像Django在某个值不唯一的情况下自动返回的错误一样。我使用了一个(ModelForm),并调整了模型中的所有内容。
7条答案
按热度按时间j9per5c41#
大多数Django视图,例如Django管理员,将无法处理
save
方法中的验证错误,因此您的用户将得到500个错误。您应该在模型表单、模型的
clean
方法上进行验证,或者通过向模型字段添加验证器来进行验证。然后仅当模型表单数据有效时才调用save()
,在这种情况下,数据“足以保存”。1qczuiv02#
Bastian,我向你解释我的代码模板,我希望这对你有帮助:
从django1.2开始,它可以在model上写验证代码,当我们使用modelforms时,instance.full_clean()在表单验证时被调用。
在每个模型中,我用一个自定义函数覆盖
clean()
方法(在modelform验证时,这个方法会自动从full_clean()调用):然后在
rules.py
文件中写入业务规则,并将pre_save()
连接到自定义函数,以防止保存错误状态的模型:从问题.模型导入问题
然后,modelform调用model的clean方法,我的custon函数检查状态是否正确,或者引发一个错误,由model form处理。
为了在表单上显示错误,您应该在表单模板上包含以下内容:
原因是模型确认错误与non_field_errors错误字典条目绑定。
当您从表单中保存或删除模型时,您应该记住可能会引发错误:
此外,您还可以将错误添加到无模型表单的表单字典中:
请记住,这段代码不会在保存()方法上执行:注意,当你调用模型的保存()方法时,full_clean()不会自动被调用,也不会作为ModelForm验证的结果被调用,然后,你可以在no modelforms的表单字典中添加错误:
ffdz8vbo3#
我认为这是Django1.2+更明确的方法
在表单中,它将作为non_field_error出现,在其他情况下,如DRF,您必须检查此案例手册,因为它将是500错误。
8iwquhpp4#
在Django文档中,他们在
.save
方法中引发了ValueError
,这可能对你有用。https://docs.djangoproject.com/en/3.1/ref/models/instances/
6ovsh4lw5#
如果要对模型进行验证,可以对模型使用
clean()
或clean_fields
方法。*EDIT:这些是由django在执行
save()
之前调用的,验证错误以用户友好的方式处理 * 是不正确的,感谢@布拉德的回复。这些
clean
和clean_fields
方法在保存模型之前被Django的表单验证器调用(例如在django admin中,在这种情况下,您的验证错误会得到很好的处理),但在save()
上不会被调用,DRF序列化器会自动调用,或者如果您使用自定义视图,在这种情况下,您必须确保它们被调用(或者用另一种方法验证,例如,将逻辑放入序列化程序的验证中)。值得强调:如果您将自定义验证逻辑直接放入
save()
中,并从那里引发ValidationError
,那么表单就不能很好地运行(例如,使用500错误中断管理),如果你想让django-admin和DRF一起工作的话,这会让事情变得真实的痛苦。基本上,您必须要么在序列化程序和clean*
方法中复制验证逻辑,要么找到一些笨拙的方法来执行验证,以便两者共享。Django关于验证错误的文档在这里。
bq9c1y666#
编辑:这个答案假设您有一个场景不允许您编辑当前实现的
User
类,因为您不是从零开始一个项目,当前实现还没有使用自定义User类,您必须找出如何通过修改Django内置的User模型行为来完成这个任务。大多数时候你可以只在你的模型中添加一个
clean
方法,但是对于内置的auth.User
模型,你不需要这样做,这个解决方案允许你为auth.User
模型创建一个clean
方法,这样ValidationError
就可以传播到调用clean方法的表单中(包括管理表单)。如果有人尝试创建或编辑
auth.User
示例,使其与现有auth.User
示例具有相同的电子邮件地址,则下面的示例将引发错误。免责声明,如果您向新用户公开注册表单,您不希望验证错误像下面我的示例那样调出用户名。我在
my_app.models
的底部有这个,但是我相信只要你把它放在某个地方,在有问题的表单之前加载,它就可以工作。frebpwbc7#