DRF: How can I validate data vs instance when many=True?

I am using a DRF serializer to update data in bulk. This is how I instantiate the serializer:

# 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 ...

And this is the serializer:

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

So I'm relying on the default ListSerializer class that is triggered when the serializer is instantiated with the many=True argument.

My validation fails because the validate method does not have an "instance" argument like the update method does; and self.instance is the entire queryset, not only the "current" instance.

So this instruction fails:

if instance.must 

because "instance" is a queryset and doesn't have a "must" attribute.

At the moment, my only solution is to get the object from the database using the id I have in the "data" argument; but that would result in a lot of queries.

Is there any way to validate data vs instance?

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