Лучшая архитектура для динамической проверки и сохранения поля
Я ищу хорошую архитектуру для решения моей проблемы. Я использую django rest framework для создания API. Я получаю список dict, который содержит id и список значений. Список значений должен быть проверен в соответствии с id.
Пример моего кода:
class AttributesSerializer(serializers.Serializer):
id = serializers.PrimaryKeyRelatedField(queryset=Attribute.objects.all(), source="attribute", required=True)
values = serializers.ListField()
def validate(self, validated_data):
attribute = validated_data["attribute"]
values = validated_data["values"]
# This function returns the corresponding field according to attribute
values_child_field = get_values_field(attribute)
self.fields["values"].child = values_child_fields
new_values = self.fields["values"].run_child_validation(values)
set_value(validated_data, "values", new_values)
return validated_data
class SerializerExample(serializers.Serializer):
attributes = AttributesSerializer(many=True)
Я хочу разобрать json следующим образом:
{
"attributes": [
{"id": 124, "values": ["value"]},
{"id": 321, "values": [42]},
{
"id": 18,
"values": [
{
"location": {"type": "Point", "geometry": {...}},
"address": "an address",
}
],
},
]
}
В настоящее время этот код не работает. Кажется, что DRF не пытается проверить все записи значений для каждой итерации. Я не понимаю, почему... Думаю, я мог бы заставить его работать без использования этого fields["values"] для валидации и просто получить поле и использовать его напрямую, но мне нужно это поле для последующего сохранения.
Как вы думаете, моя архитектура подходит? Какой хороший способ анализа данных такого типа с помощью DRF?
Спасибо.
Я думаю, вам следует использовать ListField
с JSONField
в качестве дочернего аргумента для поля values
.
validators = {
TinyurlShortener.DataType.TEXT: serializers.CharField(),
TinyurlShortener.DataType.INTEGER: serializers.IntegerField(),
TinyurlShortener.DataType.DATETIME: serializers.DateTimeField(),
TinyurlShortener.DataType.BOOL: serializers.BooleanField(),
}
class AttributesSerializer(serializers.Serializer):
id = serializers.PrimaryKeyRelatedField(queryset=Attribute.objects.all(), source="attribute", required=True)
values = serializers.ListField(
child=serializers.JSONField()
)
def validate(self, attrs):
attribute = attrs.get('id')
field = validators[attribute.attribute_type]
for v in attrs['values']:
field.run_validation(json.loads(v.replace("'", '"')))
return super().validate(attrs)
class BaseObjectApiInputSerializer(serializers.Serializer):
category_id = serializers.PrimaryKeyRelatedField(
queryset=Category.objects.all()
)
attributes = AttributesSerializer(many=True)