Вопрос

<Сильный> Вопрос : Как написать сухой код для проверки поля в виде формы, так и для сериала?

<Сильный> Пример : У меня есть простое приложение Django с формой модели, которая проверяет поле passengers для Order:

def clean_passengers(self):
    passengers = self.cleaned_data['passengers']
    if passengers > self.flight.available_seats:
        raise forms.ValidationError(
            _(u'''Passengers count can`t be greater then seats count'''))
    return passengers
.

и тот же код для проверки в сериализатор Order:

def validate_passengers(self, attrs, source):
    passengers = attrs[source]
    if passengers > self.flight.available_seats:
        raise serializers.ValidationError(
            _(u'''Passengers count can`t be greater then seats count'''))
    return attrs
.

Это не высохнет, и я пишу же логику дважды.Как я могу избежать этого?Может быть, я могу наследую сериализатор из формы или что-то вроде этого.

Это было полезно?

Решение

Вы можете использовать свой сериализатор для десериализации и проверки данных внутри метода is_valid вашего формы.

class MyModelForm(ModelForm):
    def is_valid(self):
        # Call super's is_valid to populate cleaned_data and do basic field validation
        valid = super(MyModelForm, self).is_valid()
        if not valid:
            return False

        serializer = MyModelSerializer(data=self.cleaned_data)
        return serializer.is_valid()
.

Другие советы

Здесь моя реализация многоразового класса валидации для моделей форм.Все родные джанго вещи здесь, кроме переписанного метода get_serializer.Проверенное рабочее состояние с Django 1.8.13.

class RestFrameworkValidationModelForm(forms.ModelForm):
    serializer_class = None

    def get_serializer(self, *args, **kwargs):
        """
        Return the serializer instance that should be used for validating and
        deserializing input, and for serializing output.
        """
        assert self.serializer_class is not None, (
            "'%s' should either include a `serializer_class` attribute, "
            "or override the `get_serializer()` method."
            % self.__class__.__name__
        )

        return self.serializer_class(*args, **kwargs)

    def is_valid(self):
        if super(RestFrameworkValidationModelForm, self).is_valid():
            serializer = self.get_serializer(data=self.cleaned_data)
            valid = serializer.is_valid()
            self.add_error(None, serializer.errors)
            return valid
        return False
.

А вот пример использования:

class ExperimentForm(RestFrameworkValidationModelForm):
    serializer_class = ExperimentSerializer

    class Meta:
        model = Experiment
        exclude = []
.

I would suggest putting all validation (when possible) into the model (validators or clean).

ModelForm and ModelSerializer then use the mode-validation.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top