question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot use SerializerMutation with model's id

See original GitHub issue

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
            ]
        )
...

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:4
  • Comments:7

github_iconTop GitHub Comments

3reactions
cutamarcommented, Mar 21, 2020

As a workaround:

class MySerializer(serializers.ModelSerializer):
    class Meta:
        model = models.MyModel
        fields = '__all__'
        extra_kwargs = {
            'id': {'read_only': False, 'required': False}
        }
2reactions
keethcommented, Nov 5, 2020

Would love to see a release with this fix in it thank you!!

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to use DRF serializers with Graphene - Stack Overflow
Consider we have model Subject. Let's create CRUD api for it. ... Int() message=ObjectField() class Arguments: id=graphene.
Read more >
Mutations - Graphene-Python
You can re-use your Django Rest Framework serializer with Graphene Django mutations. You can create a Mutation based on a serializer by using...
Read more >
GraphQL Simplistic CRUD - Sarit Ritwirune - Medium
Let's get started from naive approach with single model single endpoint not use any filter yet to keep my article short. First one...
Read more >
How to use DRF serializers with Graphene - DevPress - CSDN
from rest_framework import serializers from graphene_django.rest_framework.mutation import SerializerMutation from GeneralApp.models import ...
Read more >
Chapter 4. Graphene - Michael Stromer
Node, ) class AuthorNode(DjangoObjectType): class Meta: model = Author filter_fields = [] interfaces = (relay.Node, ) # 2. Queries can fetch nodes using...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found