DRF - повысить исключение, если какое-либо определенное поле равно None - PullRequest
0 голосов
/ 02 апреля 2019

Мне нужно сериализовать модель до JSON. Затем отправьте это JSON одному API.

Но это API требует, чтобы некоторые поля не были None.

У меня есть список этих полей. В этом случае, скажем, это просто ['telephone'], но это может быть гораздо больше.

Например:

class UserSerializer(serializers.ModelSerializer):
    telephone = serializers.CharField(source='userprofile.telephone')
    class Meta:
        model = User
        fields = ['first_name','last_name','telephone']

Сериализация:

>>> UserSerializer(user).data
>>> {'first_name':'Michael','last_name':'Jackson','telephone':None}

Поскольку для API требуются некоторые поля, такие как telephone, я хочу, чтобы с UserSerializer до raise ValidationError, когда обязательное поле None.

Так что в этом случае я не смог сериализовать user, потому что telephone - это None.

Я пробовал много вещей, включая добавление required=True к telephone, но ничего не работает.

Есть ли способ validate сериализованных данных? Обратите внимание, что я не говорю о deserialization.

Ответы [ 3 ]

1 голос
/ 03 апреля 2019

Почему проверка не работает?

Процесс проверки проходит только тогда, когда Deserialization процесс (входные данные - dict как объект), и вы пытаетесь Serialization процесс . В случае Serialization DRF предполагает, что данный объект является допустимым и, следовательно, он не требует проверки.

Источник DRF-сериализаторы


Как мы можем это сделать?

Метод-1
Сделайте ваш пользовательский объект user_data (dict объект) и передайте его сериализатору и запустите проверку.

user = User.objects.get(id=1)
dict_user_data = {"first_name": user.first_name, "last_name": user.last_name, "telephone": user.userprofile.telephone}
user_serializer = UserSerializer(data=dict_user_data)
user_serializer.is_valid(True)
user_serializer.data


Способ-2
Переопределите метод to_representation()

class UserSerializer(serializers.ModelSerializer):
    telephone = serializers.CharField(source='userprofile.telephone')

    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'telephone']

    <b>def to_representation(self, instance):
        data = super().to_representation(instance)
        for field, value in data.items():
            if value is None:
                raise SomeExceptionHere({field: "can't be None"})
        return data</b>
0 голосов
/ 02 апреля 2019

Вам нужно не проверять данные для десериализации, а проверять сериализацию.Выражения типа required = True все используются для проверки данных для десериализации.Сериализация обрабатывается в to_representation методе Сериализатора класса (который является основой для ModelSerializer )

Что вы можете сделать, переопределить to_representation и заставить метод вызывать исключение, если обязательным значением поля является None.

Возможно, вам понадобится дополнительно подклассировать классы DRF по умолчанию, такие как Поле (для поля сериализатора)и использовать ваши пользовательские классы, чтобы иметь возможность систематически предоставлять ваши функциональные возможности.Вы не хотите полагаться на required = True для этого, потому что он уже используется для другой цели (для проверки десериализации).

Я предлагаю подкласс Field class, добавьте свойство типа " required_for_read " и определите поле сериализатора с помощью этого свойства, используя свой класс настраиваемого поля.Затем в переопределенном методе to_representation найдите это свойство и создайте исключение, если поле имеет это свойство как True , но его значение равно Нет

0 голосов
/ 02 апреля 2019

Вам не нужно. Сериализаторы DRF могут сделать это прямо из коробки. Если для поля установлено значение null=False или required=True, просто сделайте это.

data = UserSerializer(data=user_data)
data.is_valid(raise_exception=True

И это все. Возникнет ошибка 400.

Если хотите, можете настроить сообщение об ошибке:

data = UserSerializer(data=user_data)
try:
    data.is_valid(raise_exception=True)
except ValidationError as e:
   return HttpResponse(status_code=400, content=e)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...