Django - 如何指定验证失败的字段?

Gre*_*reg 51 django django-models django-admin

我有这个模型,我在管理页面中显示:

class Dog(models.Model):
    bark_volume = models.DecimalField(...
    unladen_speed = models.DecimalField(...

    def clean(self):
        if self.bark_volume < 5:
            raise ValidationError("must be louder!")
Run Code Online (Sandbox Code Playgroud)

如您所见,我对模型进行了验证.但我想要发生的是管理页面显示bark_volume字段旁边的错误,而不是像现在这样的一般错误.有没有办法指定验证失败的哪个字段?

非常感谢提前.

Gre*_*reg 97

好的,我从这个答案中找到了答案.

你必须做这样的事情:

class Dog(models.Model):
    bark_volume = models.DecimalField(...
    unladen_speed = models.DecimalField(...

    def clean_fields(self):
        if self.bark_volume < 5:
            raise ValidationError({'bark_volume': ["Must be louder!",]})
Run Code Online (Sandbox Code Playgroud)


Chr*_*att 12

class Dog(models.Model):
    bark_volume = models.DecimalField(...
    unladen_speed = models.DecimalField(...

    def clean(self):
        if self.bark_volume < 5:
            if not self._errors.has_key('bark_volume'):
                from django.forms.util import ErrorList
                self._errors['bark_volume'] = ErrorList()
            self._errors['bark_volume'].append('must be louder!')
Run Code Online (Sandbox Code Playgroud)

这至少适用于表格.从来没有尝试过模型本身,但方法应该是相同的.但是,从Django文档:

当您使用ModelForm时,对is_valid()的调用将对表单中包含的所有字段执行这些验证步骤.(有关详细信息,请参阅ModelForm文档.)如果您计划自己处理验证错误,或者您已从ModelForm中排除了需要验证的字段,则只需要调用模型的full_clean()方法.

和...

请注意,调用模型的save()方法时,也不会自动调用full_clean(),也不会因模型化验证而调用.如果要在ModelForm之外运行模型验证,则需要手动调用它.

所以,基本上,除非你有充分的理由在模型上进行现场清理,否则你应该在表格上进行.该代码如下所示:

class DogForm(forms.ModelForm):

    def clean(self):
        bark_volume = self.cleaned_data.get('bark_volume')
        if bark_volume < 5:
            if not self._errors.has_key('bark_volume'):
                from django.forms.util import ErrorList
                self._errors['bark_volume'] = ErrorList()
            self._errors['bark_volume'].append('must be louder!')

        return self.cleaned_data
Run Code Online (Sandbox Code Playgroud)

这肯定会奏效.

  • 实际上提出ValidationError只是将项添加到self._errors.它是表单上所有错误的主列表. (2认同)

str*_*ics 7

要注意任何可能遇到更新版本的Django的人 - 来自接受的答案的clean_fields方法现在需要一个"排除"参数.此外 - 我相信接受的答案也缺少对它的超级功能的调用.我使用的最终代码是:

def clean_fields(self, exclude=None):
    super(Model, self).clean_fields(exclude)

    if self.field_name and not self.field_name_required:
        raise ValidationError({'field_name_required':["You selected a field, so field_name_required is required"]})
Run Code Online (Sandbox Code Playgroud)


Cha*_*ase 7

缩写,来自django 文档

def clean(self):
    data = self.cleaned_data
    subject = data.get("subject")

    if subject and "help" not in subject:
        msg = "Must put 'help' in subject."
        self.add_error('subject', msg)

    return data
Run Code Online (Sandbox Code Playgroud)


Mik*_*one 6

使用clean_特定于该字段的方法:

class DogForm(forms.ModelForm):
    class Meta:
        model = Dog

    def clean_bark_volume(self):
        if self.cleaned_data['bark_volume'] < 5:
            raise ValidationError("must be louder!")
Run Code Online (Sandbox Code Playgroud)

请参阅" 表单验证"页面的clean<fieldname>部分.另外,请确保使用而不是表单字段本身; 后者可能有旧数据.最后,在表单而不是模型上执行此操作.cleaned_data

  • 可以有多个`clean_ <fieldname>`方法; 每个都将轮流检查,其错误将附加到相关字段. (2认同)

Mon*_*lik 5

验证这种特殊情况的最简单方法是:

from django.core.validators import MinValueValidator
from django.utils.translation import ugettext_lazy as _

class Dog(models.Model):
    bark_volume = models.DecimalField(
        ..., validators=[MinValueValidator(5, message=_("Must be louder!"))]
Run Code Online (Sandbox Code Playgroud)

Django 关于验证器的文档:https : //docs.djangoproject.com/en/dev/ref/validators/