New SerializerMutation which is conform with ApolloClient
See original GitHub issueHello, I’m a bit new to the whole graphene django dev scene so it might be that I dont have everything right
So I’m working on a project that uses ApolloClient on the frontend and I wanted to get the automatic cache updates working. For that to work, the arguments of the mutation have to be the individual fields of that ObjectType to be mutated. Also it should return the ObjectType directly and not a wrapping of that ObjectType.
Somehow I was unable to get my backend running like this with the current graphene django combination. So I started digging and modified the SerializerMutation from graphene-django a bit. Below is what I came up with so far. Maybe some experts can comment on this. I don’t know why the ClientIDMutation is used currently. I skipped that in my implementation and just used graphene.Mutation directly. Well let me know if this is any use or not. In case of the former I would be glad to polish this up and make a pull request.
class MySerializerMutation(graphene.Mutation):
class Arguments:
pass
@classmethod
def __init_subclass_with_meta__(cls, serializer_class=None, output_type=None, lookup_field=None, model_class=None, **options):
serializer_class = serializer_class
for k, v in fields_for_serializer(
serializer_class(), (), (), is_input=True).items():
setattr(cls.Arguments, k, v)
setattr(cls, 'Output', output_type)
if model_class is None:
serializer_meta = getattr(serializer_class, 'Meta', None)
if serializer_meta:
model_class = getattr(serializer_meta, 'model', None)
_meta = SerializerMutationOptions(cls)
_meta.lookup_field = lookup_field
_meta.model_operations = ['update', 'create']
_meta.serializer_class = serializer_class
_meta.model_class = model_class
super(MySerializerMutation, cls).__init_subclass_with_meta__(_meta=_meta, **options)
@classmethod
def get_serializer_kwargs(cls, root, info, **input):
lookup_field = cls._meta.lookup_field
model_class = cls._meta.model_class
if model_class:
if 'update' in cls._meta.model_operations and lookup_field in input:
instance = get_object_or_404(model_class, **{
lookup_field: input[lookup_field]})
elif 'create' in cls._meta.model_operations:
instance = None
else:
raise Exception(
'Invalid update operation. Input parameter "{}" required.'.format(
lookup_field
))
return {
'instance': instance,
'data': input,
'context': {'request': info.context}
}
return {'data': input, 'context': {'request': info.context}}
@classmethod
def mutate(cls, root, info, **input):
kwargs = cls.get_serializer_kwargs(root, info, **input)
serializer = cls._meta.serializer_class(**kwargs)
if serializer.is_valid():
obj = serializer.save()
return obj
else:
errors = [
ErrorType(field=key, messages=value)
for key, value in serializer.errors.items()
]
return cls(errors=errors)
Issue Analytics
- State:
- Created 5 years ago
- Comments:8 (2 by maintainers)
Top GitHub Comments
hey @spflueger, when I implemented the serialiser mutation I mistakenly decided to not wrap the returned fields in a new type. I have a custom version of serialiser mutation to fix this, which works similar to what I proposed here: #386
I’ll see if I can send the PR soon 😃
I think this is related to https://github.com/graphql-python/graphene-django/issues/376