web-dev-qa-db-ja.com

Django-検証が失敗するフィールドを指定する方法?

管理者ページに表示しているこのモデルがあります:

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!")

ご覧のとおり、モデルに検証を加えました。しかし、私が起こりたいのは、現在のような一般的なエラーではなく、bark_volumeフィールドの横にエラーを管理ページに表示することです。検証が失敗するフィールドを指定する方法はありますか?

事前に感謝します。

51
Greg

OK、私はそれを理解しました この答えから

このようなことをしなければなりません:

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!",]})
96
Greg
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!')

少なくともフォームでは機能します。モデル自体でそれを試したことはありませんが、方法論は同じでなければなりません。ただし、Django docs:

ModelFormを使用すると、is_valid()の呼び出しにより、フォームに含まれるすべてのフィールドに対してこれらの検証手順が実行されます。 (詳細については、ModelFormのドキュメントを参照してください。)検証エラーを自分で処理する場合、または検証が必要なフィールドをModelFormから除外した場合にのみ、モデルのfull_clean()メソッドを呼び出す必要があります。

そして...

モデルのsave()メソッドを呼び出すとき、またはModelForm検証の結果として、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

そして、それは確かに機能します。

12
Chris Pratt

新しいバージョンの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"]})
7
streetlogics

フィールドに固有の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!")

フォーム検証 ページのclean<fieldname>部分を参照してください。また、フォームフィールド自体の代わりにcleaned_dataを使用してください。後者には古いデータが含まれている場合があります。最後に、モデルではなくフォームでこれを行います。

6
Mike DeSimone

この特定のケースを検証する最も簡単な方法は次のとおりです。

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!"))]

バリデータに関するDjangoのドキュメント: https://docs.djangoproject.com/en/dev/ref/validators/

4
Monika Sulik

Django docs の略語:

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
2
Chase