While I've been able to make my application work, I have some concerns about doing things the right way. Therefore there is something I "do not understand" :
In the documentation, here, in the QuestionMutation
class, there is a question
attribute. What does that actually mean ? It says that it defines the response and I don't understand what this means.
class QuestionType(DjangoObjectType):
class Meta:
model = Question
class QuestionMutation(graphene.Mutation):
class Arguments:
# The input arguments for this mutation
text = graphene.String(required=True)
id = graphene.ID()
# The class attributes define the response of the mutation
question = graphene.Field(QuestionType)
@classmethod
def mutate(cls, root, info, text, id):
question = Question.objects.get(pk=id)
question.text = text
question.save()
# Notice we return an instance of this mutation
return QuestionMutation(question=question)
And in my code I've been able to do this :
class UserType(DjangoObjectType):
class Meta:
model = User
fields = (
'id',
'username',
'password',
'email',
'first_name',
'last_name',
'is_active',
'group_ids',
)
full_name = graphene.String() # Python property
full_identification = graphene.String() # Python property
class UpdateUser(graphene.Mutation):
# --------> I could comment these and no problem. Why ? <--------
# id = graphene.ID()
# username = graphene.String()
# email = graphene.String()
# first_name = graphene.String()
# last_name = graphene.String()
# is_active = graphene.Boolean()
class Arguments:
id = graphene.ID()
username = graphene.String()
email = graphene.String()
first_name = graphene.String()
last_name = graphene.String()
is_active = graphene.Boolean()
class Meta:
output = UserType
@login_required
def mutate(self, info, **kwargs):
user = get_object_or_404(User, id=kwargs['id'])
for attr, value in kwargs.items():
setattr(user, attr, value)
user.save()
return user
# I'm not returning explicit UserType, is it a problem ?
# I actually do it with the Meta class. I guess it is the same for this ?
and it works whereas I didn't specify anything for the response attributes. And I don't even return the same kind of thing. Can someone explain if I'm doing it wrong ?
You can see here that if I call this mutation :
mutation {
updateUser (
id: 42
username: "updated_user"
firstName: "updated"
lastName: "user"
email: "updated.user@test.com"
) {
id
username
firstName
lastName
email
}
}
I'm able to get this answer even without return values :
{
"data": {
"updateUser": {
"id": "42",
"username": "updated_user",
"firstName": "updated",
"lastName": "user",
"email": "updated.user@test.com"
}
}
}
I also asked the question HERE and it appears that there is more information about these configuration THERE.
Finally, since I've set the ouput = UserType
and model = User
, my UserType
and User
classes are duck typed and it works like a charm even without defining return fields (the ones commented in the question).
In other words, this sample of code appears to be a correct way to do this, and the official documentation doesn't do it like this but it is intented to work like this too (as you can read in the code docs).
class UserType(DjangoObjectType):
class Meta:
model = User
fields = (
'id',
'username',
'password',
'email',
'first_name',
'last_name',
'is_active',
'group_ids',
)
full_name = graphene.String() # Python property
full_identification = graphene.String() # Python property
class UpdateUser(graphene.Mutation):
# We can omit return fields since UserType is defined as output ('output = UserType')
# and UserType has already defined fields in its class.
class Arguments:
id = graphene.ID()
username = graphene.String()
email = graphene.String()
first_name = graphene.String()
last_name = graphene.String()
is_active = graphene.Boolean()
class Meta:
output = UserType
@login_required
def mutate(self, info, **kwargs):
user = get_object_or_404(User, id=kwargs['id'])
for attr, value in kwargs.items():
setattr(user, attr, value)
user.save()
return user
# Returning a User can be done since it is linked to the UserType and we
# said we return a UserType with 'output = UserType'