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 вместо общей ошибки, такой как сейчас. Есть ли способ указать, в каком поле выполняется проверка?
Большое спасибо заранее.
Ответы
Ответ 1
ОК, я понял это из этого ответа.
Вам нужно сделать что-то вроде этого:
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!",]})
Ответ 2
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:
Когда вы используете ModelForm, вызов is_valid() будет выполнять эти шаги проверки для всех полей, которые включены в форму. (Дополнительную информацию см. В документации ModelForm.) Вам нужно будет только вызвать метод full_clean() моделей, если вы планируете самостоятельно обрабатывать ошибки проверки, или если вы исключили поля из ModelForm, которые требуют проверки.
А...
Обратите внимание, что full_clean() не будет вызываться автоматически при вызове метода save() моделей или в результате проверки ModelForm. Вам нужно будет вызвать его вручную, если вы хотите запустить проверку модели за пределами 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
И это будет работать, конечно.
Ответ 3
Обратите внимание на всех, кто может столкнуться с этим с более новой версией 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"]})
Ответ 4
Используйте метод 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
вместо самого поля формы; последние могут иметь старые данные. Наконец, сделайте это на форме, а не на модели.
Ответ 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!"))]
Документация Django о валидаторах: https://docs.djangoproject.com/en/dev/ref/validators/
Ответ 6
сокращенно, из 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