Сделать набор полей обязательными или необязательными динамически в DRF - PullRequest
0 голосов
/ 08 мая 2020

Например, у меня есть следующий сериализатор:

class MySerializer(serializers.ModelSerializer):
    field1 = serializers.CharField(required=True)
    field2 = serializers.CharField(required=True)
    field3 = serializers.CharField(required=True)

    field4 = serializers.CharField(required=False)
    field5 = serializers.CharField(required=False)

Первые 3 поля обязательны, а последние 2 - нет. Что я хочу сделать, если в необработанных данных присутствуют только 3 обязательные поля, это нормально, но как только field4 или field5 присутствует в необработанных данных I хотите, чтобы все поля с required=False превратились в required=True, то есть, если я введу какие-либо необязательные поля, все остальные необязательные поля станут обязательными. что я могу ввести ноль необязательных полей или их все.

Спасибо.

1 Ответ

0 голосов
/ 09 мая 2020

Я создал следующий миксин, чтобы решить эту проблему:

class RequiredTogetherFieldsMixin:
    """
    Allow to specify few fields as required together. They are not required until at leas one field from
    this set is filled with data. That would trigger all other fields specified in 'required_together_fields'
    became required. That is ine can leave all required together fields empty or fill tem all.
    """
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        if not self.fields.keys() >= set(self.required_together_fields):
            raise serializers.ValidationError(
                {'required_together_fields': error_codes.REQUIRED_TOGETHER_WRONG_FIELDS_NAMES},
                code='wrong_required_together_fields'
            )

        required_fields_in_data = set(self.required_together_fields).intersection(self.initial_data)

        if required_fields_in_data:
            for field_name, field in self.fields.items():
                if field_name in self.required_together_fields:
                    field.required = True

    required_together_fields = ()

Все, что вам нужно сделать, это указать required_together_fields в сериализаторе и унаследовать его от этого миксина. Как только по крайней мере одно из полей будет заполнено данными, все остальные поля также станут required.

...