yezyilomo / django-restql

Turn your API made with Django REST Framework(DRF) into a GraphQL like API.
https://yezyilomo.github.io/django-restql
MIT License
616 stars 43 forks source link

Error with nested validate #214

Open alepn opened 3 years ago

alepn commented 3 years ago

When I use validate data method on a nested serializer, I receive the following message:

"create is not a valid operation, valid operations for this request are add, create, remove, update"

yezyilomo commented 3 years ago

Can you show us the way you are using validate data method on your nested serializer so that we at least get a starting point, posting a piece of code which you think is causing that error would be very helpful to anyone who wants to help you. It’s better to mention the version of django-restql which you are using to make things easier.

alepn commented 3 years ago

MODELS

class Profile(models.Model):
    name = models.CharField('Name', max_length=80)

class Email(models.Model):
    profile = models.ForeignKey(Profile)
    email = models.CharField('Email', max_length=80, unique=True)

SERIALIZERS

from django_restql.mixins import DynamicFieldsMixin
from django_restql.serializers import NestedModelSerializer

class EmailSerializer(DynamicFieldsMixin, NestedModelSerializer):

    def validate(self, data):
        if data['email']:
            q = Email.objects.filter(email=data['email'])
            if self.instance:
                q = q.exclude(pk=self.instance.id)
            if q.exists():
                raise serializers.ValidationError("Email already exists.")
        return data

    class Meta:
        model = Email
        fields = ['profile','email']

class ProfileSerializer(DynamicFieldsMixin, NestedModelSerializer):
    email_set = NestedField(EmailSerializer, many=True, required=False, allow_null=True)
    class Meta:
        model = Email
        fields = ['name','email_set']

Tested with django-restql versions: 0.10.2 and 0.11.2

yezyilomo commented 3 years ago

There is nothing wrong with your code, I think the problem is on the way you are sending your request, you are probably adding space(s) before or after the word create.

NOTE: "create " != "create" != " create" != " create " Make sure you are not leaving spaces before or after the the operation "create"

alepn commented 3 years ago

The request body is right. This message appears only when I use the validate. When validate is removed, the request works normaly.

yezyilomo commented 3 years ago

I think there's something wrong in your code, I have tried to reproduce your scenario, to me it works just fine you don't even need the validate method the DRF handles it for you, but even if you use it everything works fine. if I create email it creates successfully, if I try to re-create the same email it tells me that it already exists.

alepn commented 3 years ago

Yes, it works until the step you've tested. But if you try to re-send the request, with a new valid email, the DRF shows a fk constraint error on nested item. I think the fk id on nested item is lost when DRF raises a exception.

alepn commented 3 years ago

I tried to use the validate on serializer, but I noticed that the DRF constraint validation always is throwed before the validate method on serializer.