这是验证 Django 模型字段的方法吗? [英] Is this the way to validate Django model fields?

查看:23
本文介绍了这是验证 Django 模型字段的方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,当一个人创建一个 Django 应用程序时,数据在插入到模型实例之前由表单验证,然后将其写入数据库.但是如果我想在数据模型层创建一个额外的保护层,我在当前的最佳实践"之下做了什么?我正在努力确保审稿人的姓名不能被省略或留空.我应该像我在这里所做的那样在clean"方法中放置任何自定义验证,然后让save"调用full_clean"调用clean"吗?如果不是,首选方法是什么?谢谢.

As I understand it, when one creates a Django application, data is validated by the form before it's inserted into a model instance which is then written to the database. But if I want to create an additional layer of protection at the data model layer, is what I've done below the current "best practice?" I'm trying to ensure that a reviewer's name cannot be omitted nor be left blank. Should I be putting any custom validation in the 'clean' method as I've done here and then have 'save' call 'full_clean" which calls 'clean'? If not, what's the preferred method? Thanks.

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.来自 关于 full_clean 的 django 文档:

Firstly, you shouldn't override full_clean as you have done. From the django docs on full_clean:

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

Model.full_clean(exclude=None)
This method calls Model.clean_fields(), Model.clean(), and Model.validate_unique(), in that order and raises a ValidationError that has a message_dict attribute containing errors from all three stages.

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

So the full_clean method already calls clean, but by overriding it, you've prevented it calling the other two methods.

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

Secondly, calling full_clean in the save method is a trade off. Note that full_clean is already called when model forms are validated, e.g. in the Django admin. So if you call full_clean in the save method, then the method will run twice.

通常不希望 save 方法引发验证错误,有人可能会调用 save 而没有捕捉到由此产生的错误.但是,我喜欢您调用 full_clean 而不是在 save 方法本身中进行检查 - 这种方法允许模型表单首先捕获问题.

It's not usually expected for the save method to raise a validation error, somebody might call save and not catch the resulting error. However, I like that you call full_clean rather than doing the check in the save method itself - this approach allows model forms to catch the problem first.

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

Finally, your clean method would work, but you can actually handle your example case in the model field itself. Define your CharField as

name = models.CharField(max_length=128)

空白选项将默认为 False.如果该字段为空,则在运行 full_clean 时将引发 ValidationError.将 default=None 放在您的 CharField 中不会造成任何伤害,但是当您实际上不允许 None 作为一个值.

The blank option will default to False. If the field is blank, a ValidationError will be raised when you run full_clean. Putting default=None in your CharField doesn't do any harm, but it is a bit confusing when you don't actually allow None as a value.

这篇关于这是验证 Django 模型字段的方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆