Django Rest Framework — определите обязательные поля

ИЗМЕНИТЬ

Я просто хочу вызвать исключение, когда я делаю BrokerSerializer(user).data и любое из значений равно None

Я использую DRF для сериализации объектов, чтобы экспортировать их через API, я не использую его для создания объектов.

Ищете самый простой способ сделать поля обязательными при сериализации модели.

API требует, чтобы некоторые поля не были нулевыми, поэтому я хочу поднять APIMissingDataException, если какое-либо из них равно null/None.

Я старался:

class BrokerSerializer(serializers.ModelSerializer):
    import_id = serializers.IntegerField(source='pk')
    deleted = serializers.SerializerMethodField()
    full_name = serializers.CharField(source='userprofile.get_display_name')
    phone_work = serializers.CharField(source='userprofile.contact_information.telephone')
    email_work = serializers.CharField(source='userprofile.contact_information.email')

class Meta:
    model = User
    fields = ['import_id', 'deleted', 'full_name', 'phone_work', 'email_work']
    required_fields = fields


def validate(self, attrs):
    super().validate(attrs)
    if not all([attrs.get(fieldname) for fieldname in self.Meta.required_fields]):
        raise APIMissingDataException()
    return attrs

def get_deleted(self, obj):
    return 0

Но функция validate почему-то не вызывается. Я не хочу явно определять все поля только для того, чтобы добавить к ним required=False параметров.

In [10]: b = BrokerSerializer(User.objects.first())                                                                                                                                                  

In [11]: b.data                                                                                                                                                                                       

# It should have raised exception since there are None
Out[11]: {'import_id': 1, 'deleted': 0, 'full_name': None, 'phone_work': None, 'email_work': None}

In [12]: b = BrokerSerializer(data=User.objects.first())                                                                                                                                             

In [13]: b.is_valid()                                                                                                                                                                                
Out[13]: False

In [14]: b.data                                                                                                                                                                                      
Out[14]: {}

Есть более удобный способ?


person Milano    schedule 02.04.2019    source источник
comment
Вы возвращаете attrs из своего метода validate? Не могли бы вы поделиться дополнительным кодом вашего класса сериализатора и модели User?   -  person Devang Padhiyar    schedule 02.04.2019
comment
Нет, не знаю, но метод validate даже не вызывается. Я думал, что он вызывается автоматически при сериализации модели. Больше ничего нет. Предположим, что пользовательская модель содержит эти поля или в сериализаторе есть методы, которые их извлекают.   -  person Milano    schedule 02.04.2019
comment
Вы вызываете метод is_valid() вашего сериализатора?   -  person Devang Padhiyar    schedule 02.04.2019
comment
покажите нам фрагмент кода, который вызывает сериализатор и/или просмотр + запрос, который вы сделали   -  person Linovia    schedule 02.04.2019
comment
@Linovia Я добавил это внизу вопроса. Просто вызывая его через оболочку   -  person Milano    schedule 02.04.2019
comment
Пожалуйста, добавьте свои ошибки сериализатора: я имею в виду b.errors в вашем случае.   -  person M.Fooladgar    schedule 02.04.2019
comment
Я не хочу сериализовать словари, поэтому b.is_valid не имеет смысла. b.errors возвращает сообщение о том, что ожидался dict.   -  person Milano    schedule 02.04.2019


Ответы (2)


Я надеюсь, что этот ответ также применим здесь :)

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

person JPG    schedule 03.04.2019

DRF имеет встроенные методы для обработки этого.

name = serializers.CharField(label="name field",required=True, allow_blank=False, allow_null=False)

Затем используйте serializer.is_valid() для проверки данных.

Дополнительные сведения см. в этом.

person Albin Antony    schedule 02.04.2019
comment
Нет, это не работает. Есть required=True, который возвращает None. - person Milano; 02.04.2019
comment
required=True, насколько я знаю, для десериализации - person Milano; 02.04.2019