модели django предлагают что-то похожее на формы 'clean_ <fieldname>()? - PullRequest
4 голосов
/ 22 марта 2012

Я пытаюсь перенести все связанные с бизнес-логикой проверки в модели, вместо того чтобы оставлять их в формах. Но здесь у меня сложная ситуация, для которой мне нравится консультироваться с SO-сообществом.

В моей RegistrationForm (модельной форме) у меня есть следующая проверка для конкретного поля, чтобы убедиться, что входной адрес электронной почты еще не существует.

def clean_email(self):
    email = self.cleaned_data['email']

    if ExtendedUser.objects.filter(email=email).exists():
        raise ValidationError('This email address already exists.')
    return email

Если бы я перенес эту валидацию на модели, согласно официальному документу, я бы поместил ее в clean() соответствующей модели, ExtendedUser. Но в документе также упоминается следующее:

Любые исключения ValidationError, вызванные Model.clean (), будут сохранены в специальном ключе ключа словаря ошибок, NON_FIELD_ERRORS, который используется за ошибки, которые связаны со всей моделью, а не с конкретной поле

Это означает, что с clean() я не могу связать возникшие из-за этого ошибки с конкретными полями. Мне было интересно, если модели предлагают что-то похожее на формы "clean_<fieldname>(). Если нет, куда бы вы поместили эту логику проверки и почему?

Ответы [ 2 ]

3 голосов
/ 22 марта 2012

Вы можете преобразовать свой чистый метод в validator и включить его при объявлении поля.

Другой вариант - создать подкласс для поля модели и переопределить его чистый метод.

Однако не существует прямого эквивалента определения clean_<field name> методов, которые вы можете сделать для форм. Вы даже не можете назначить ошибки отдельным полям, , как вы можете сделать для форм

1 голос
/ 22 марта 2012

Как указано в комментарии, я считаю, что вы должны обрабатывать эту проверку на уровне модели.Если вы все еще чувствуете, что было бы лучше сделать это ближе к модели, и, поскольку они не могут быть изменены, я бы посоветовал изменить непосредственно на уровне БД:

ALTER TABLE auth_user ADD UNIQUE (email)

Что плохоспособ добавить ограничение unique=True в модель User без проверки подлинности.

В соответствии с запросом, я думаю, что хороший способ настройки различных форм должен быть сделан путем наследования от базовой модели.Хороший пример этого можно найти в django-registration .Единственное отличие состоит в том, что вместо родительской формы, унаследованной от forms.Form, вы бы сделали ее formForm:

class MyBaseModelForm(ModelForm):
    class Meta:
        model = MyModel

Затем вы можете наследовать ее и создавать различные формы из этой базовой модели:

class OtherFormWithCustomClean(MyBaseModelForm):
    def clean_email(self):
       email = self.cleaned_data['email']
       if ExtendedUser.objects.filter(email=email).exists():
          raise ValidationError('This email address already exists.')
    return email
...