SerializerMutation seems to remove id and insert clientMutationId into the mutation input specification.
Therefore, when I try to follow the tutorial at https://docs.graphene-python.org/projects/django/en/latest/mutations/ under Create/Update Operations it cannot work as described: id is not exposed and so it cannot work as a lookup_field.
As such, I cannot find a way to use a SerializerMutation to update based on the instance id. Am I using this correctly? The Django id field is not shadowed by clientMutationID, just removed from the input spec.
From Documentation:
from graphene_django.rest_framework.mutation import SerializerMutation
from .serializers import MyModelSerializer
class AwesomeModelMutation(SerializerMutation):
class Meta:
serializer_class = MyModelSerializer
model_operations = ['create', 'update']
lookup_field = 'id'
My code:
class CompanyType(DjangoObjectType):
class Meta:
model = Company
fields = '__all__'
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model = Company
# fields = '__all__'
fields = ['pk', 'id', 'name']
class CompanyMutation(SerializerMutation):
class Meta:
serializer_class = CompanySerializer
lookup_field = 'id'
class Mutation(graphene.ObjectType):
company = CompanyMutation.Field()
A mutation like the below should work to update the Company instance's name with id=1, but the graphql service does not accept an id.
mutation {
company(input: {id: 1, name: "Updated Name"}) {
id
name
}
}
Replacing id:1 with clientMutationId:"1" just creates a new Company with the provided name.
If I modify line 38 of rest_framework/mutation.py as follows then it works as I expect it to:
...
def fields_for_serializer(
serializer,
only_fields,
exclude_fields,
is_input=False,
convert_choices_to_enum=True,
):
fields = OrderedDict()
for name, field in serializer.fields.items():
is_not_in_only = only_fields and name not in only_fields
is_excluded = any(
[
name in exclude_fields,
field.write_only
and not is_input, # don't show write_only fields in Query
field.read_only and is_input # don't show read_only fields in Input
and name not in ['id', 'pk'], # ADDED TO ALLOW FOR ID-BASED PARTIAL UPDATE
]
)
...
As a workaround:
class MySerializer(serializers.ModelSerializer):
class Meta:
model = models.MyModel
fields = '__all__'
extra_kwargs = {
'id': {'read_only': False, 'required': False}
}
Also facing this issue.
This issue was introduced in #882 as DRF considers primary key fields as read_only.
I ran into the same issue, and was able to get past it using something similar to @hairypalm's fix in his initial post. However, should the solution be for it to work as expected with clientMutationID? Or maybe work with either that or id/pk? I'm new to GraphQL, so I'm all ears for best practices. If it does default to using clientMutationID, the docs would need to be updated I believe.
Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
Hi, Looks like the bug fix is now merged, but not released yet. Thanks a lot for the fix. I am wondering if there will be another release with this fix soon?
Would love to see a release with this fix in it thank you!!
Most helpful comment
As a workaround: