Django run_validation удаление MultiValueDict из QueryDict

У меня есть вложенное поле сериализатора на сериализаторе, который принимает Multipart/form-data (json + изображения). При помощи run_validation происходит удаление данных вложенного поля сериализатора из QueryDict. Вот код:

class CreateSerializer(ModelSerializer[Dress]):
    dress_sizes = SizeSerializer(many=True, required=False)

    def run_validation(self, data: Any = ...) -> Any | None:
        return super(CreateSerializer, self).run_validation(data)

    def validate(self, data):
        return super().validate(data)

Вот данные, которые я получаю в методе run_validation:

< QueryDict: {
  'file_name': ['swimsuit.svg'],
  'dress_sizes': [
    [{
      'size': 'xs'
    }, {
      'size': 's'
    }, {
      'size': 'm'
    }, {
      'size': 'l'
    }, {
      'size': 'xl'
    }]
  ],
  'image': [ < TemporaryUploadedFile: swim.svg(image / svg + xml) > ]
} >

После run_validation validate получает следующие данные:

OrderedDict([('file_name', 'swimsuit.svg'), ('image', <
  TemporaryUploadedFile: swim.svg(image / svg + xml) > )])

Здесь исчезла целая строка dress_sizes. Который необходим для создания списка объектов dress_sizes. Я сократил код, чтобы сделать его читабельным. Возможно есть какие-то несовпадения в написании, но это не суть важно. Вопрос в том, как сделать так, чтобы run_validation не удалял список размеров одежды?

В конечном итоге в методе create нет данных для dress_sizes = []. Вот метод create:

   def create(self, validated_data: Dict[str, Any]) -> Dress:
        dress_sizes = validated_data.pop("dress_sizes", [])

Причина, по которой метод run_validation удаляет данные полей вложенных сериализаторов из QueryDict, заключается в том, что метод run_validation класса ModelSerializer предназначен для проверки полей, определенных в классе сериализатора, но не вложенных сериализаторов.

Один из способов решения этой проблемы - переопределить метод to_internal_value сериализатора, чтобы вручную инстанцировать и проверять вложенные поля сериализатора. Вот пример:

class CreateSerializer(serializers.ModelSerializer):
dress_sizes = SizeSerializer(many=True, required=False)

def to_internal_value(self, data):
    dress_sizes_data = data.pop('dress_sizes', [])
    validated_data = super().to_internal_value(data)
    
    # Manually validate and save the nested serializer fields
    dress_sizes = []
    for size_data in dress_sizes_data:
        size_serializer = SizeSerializer(data=size_data)
        size_serializer.is_valid(raise_exception=True)
        dress_sizes.append(size_serializer.save())
    validated_data['dress_sizes'] = dress_sizes
    
    return validated_data

class Meta:
    model = Dress
    fields = '__all__'

При данной реализации метод to_internal_value вызывается после разбора данных запроса и перед проверкой. Он вручную извлекает данные для вложенных полей сериализатора, проверяет их и сохраняет в словаре validated_data. Затем он возвращает проверенные данные с правильно проверенными и сохраненными вложенными полями сериализатора.

Благодаря этому метод run_validation класса ModelSerializer больше не будет удалять данные dress_sizes из словаря validated_data.

Вернуться на верх