DRF: Как я могу проверить соответствие данных экземпляру, если many=True?
Я использую сериализатор DRF для массового обновления данных. Вот как я создаю экземпляр сериализатора:
# Order incoming data and DB instances
data = sorted(data, key=lambda x: x["id"])
instances = WorksheetChecklistItem.objects.filter(id__in=(row["id"] for row in data)).order_by("id")
# Serialize and save
serializer = update.WorksheetChecklistItemSerializer(instance=instances, data=data, many=True)
if not serializer.is_valid():
# ... more logic ...
А это сериализатор:
class WorksheetChecklistItemSerializer(serializers.ModelSerializer):
class Meta:
model = WorksheetChecklistItem
fields = ["id", "value", "outcome"]
def update(self, instance, validated_data):
instance.outcome = validated_data.get("outcome", instance.outcome)
instance.value = validated_data.get("value", instance.value)
instance.done = instance.outcome is not None
instance.save()
return instance
def validate(self, data):
"""Custom validation for the checklist item."""
instance = self.instance
if not instance:
raise serializers.ValidationError("Instance is required for validation") # Only update is allowed
# Validate "must" condition
if instance.must and not data.get("done"):
raise serializers.ValidationError(f"Checklist item {instance.id} is required but not completed.")
# Validate that value is a number
if instance.check_type == WorksheetChecklistItem.CheckType.VALUE and not isinstance(data.get("value"), (int, float)):
raise serializers.ValidationError(f"Checklist item {instance.id} requires a numeric value.")
return data
Итак, я полагаюсь на класс ListSerializer по умолчанию, который запускается при создании экземпляра сериализатора с аргументом many=True.
Моя проверка завершается неудачей, потому что у метода validate нет аргумента "instance", как у метода update; и self.instance - это весь набор запросов, а не только "текущий" экземпляр.
Таким образом, эта инструкция не выполняется:
if instance.must
потому что "instance" является набором запросов и не имеет атрибута "must".
На данный момент мое единственное решение - получить объект из базы данных, используя идентификатор, который у меня есть в аргументе "data"; но это привело бы к большому количеству запросов.
Есть ли какой-нибудь способ проверить данные по сравнению с экземпляром?