据我所知,在创建Django应用程序时,表单在将数据插入模型实例之前对其进行验证,然后再将模型实例写入数据库.但是,如果我想在数据模型层创建一个额外的保护层,那么我所做的是否低于当前的"最佳实践"呢?我正在努力确保审稿人的名字不会被遗漏,也不会留空.我是否应该像我在这里所做的那样,在‘CLEAN’方法中加入任何自定义验证,然后让‘SAVE’调用‘FULL_CLEAN’,后者调用‘CLEAN’?如果不是,首选的方法是什么?谢谢.

class Reviewer(models.Model):
    name = models.CharField(max_length=128, default=None)

    def clean(self, *args, **kwargs):
        if self.name == '':
            raise ValidationError('Reviewer name cannot be blank')
        super(Reviewer, self).clean(*args, **kwargs)

    def full_clean(self, *args, **kwargs):
        return self.clean(*args, **kwargs)

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

推荐答案

首先,你不应该像以前那样覆盖full_clean.从django docs on full_clean人中:

100
此方法按该顺序调用Model.clean_fields()Model.clean()Model.validate_unique(),并引发一个ValidationError,该ValidationError具有包含所有三个阶段的错误的message_dict属性.

所以full_clean方法已经调用了clean,但是通过覆盖它,您已经阻止了它调用另外两个方法.

其次,在save方法中调用full_clean是一种权衡.请注意,在验证模型表单时(例如在Django管理中)已经调用了full_clean.因此,如果在save方法中调用full_clean,则该方法将运行两次.

通常情况下,save方法不会引发验证错误,可能有人会调用save,但无法捕获结果错误.然而,我喜欢调用full_clean,而不是在save方法本身中进行判断——这种方法允许模型表单首先捕获问题.

最后,您的clean方法可以工作,但实际上您可以在模型字段本身中处理您的示例 case .将你的CharField定义为

name = models.CharField(max_length=128)

blank选项将默认为False.如果该字段为空,则在运行full_clean时将引发ValidationError.在CharField中加default=None没有任何害处,但如果你实际上不允许None作为一个值,那就有点混乱了.

Django相关问答推荐

查尔而不是瓦尔查尔加盟Django 球场

如何从列中捕获数据并将其添加到下拉菜单中,以便表单填充另一个表

无法在views.py django中验证密码

获取 Django (postgres) 中带注释字段的平均值

更改Django的创建时间字段

Django REST框架中如何从另一个视图调用API视图?

按下按钮刷新在html文件中显示的变量

如何在Django模板中有条件地传递值给with变量?

Django: 无法将我的 comments 关联到特定产品

有没有办法在Django中按需/点击仅获取和序列化一部分数据以提高性能?

如何使用来自另一个字段的信息创建字段

DecimalField 验证错误,返回不正确的值 Django

如何在不编写每个视图中的逻辑的情况下呈现值,Django?

更新或创建异步 Django ORM 实例

Django 身份验证系统修改

模板过滤器修剪任何前导leading或尾随trailing空格

Django {{ MEDIA_URL }} 空白 @DEPRECATED

__init__() 得到了一个意外的关键字参数user

django python 日期时间设置为午夜

如何在该元素中的所有应用程序之间共享元素范围的模板标签