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.