returned pk ids are string by default - how to serialize pks as int
See original GitHub issueI was surprised to discover that by default, all DjangoObjectType
schema nodes had primary key ids that were strings:
class UserType(DjangoObjectType):
id = graphene.Int(source='pk')
is_current_user = graphene.Boolean()
class Meta:
model = User
def resolve_is_current_user(self, info):
current_user = info.context.get('current_user')
if current_user:
return self.id is current_user.id
return False
class UsersQuery(graphene.ObjectType):
users = graphene.List(UserType)
def resolve_users(self, info, **kwargs):
return User.objects.all()
schema = graphene.Schema(query=ChatQuery)
gql_to_execute = """
query {
users {
id
username
isCurrentUser
}
}
"""
current_user = User.objects.get(id=1)
result = schema.execute(gql_to_execute, context_value={"current_user": current_user}
print(json.dumps(result.data, indent=4))
printed = {
"users": [
{
"id": "3",
"name": "User Three",
"username": "user3",
"isCurrentUser": false,
"photoUrl": ""
},
{
"id": "2",
"name": "User Two",
"username": "user2",
"isCurrentUser": false,
"photoUrl": ""
},
{
"id": "1",
"name": "User One",
"username": "user1",
"isCurrentUser": true,
"photoUrl": ""
}
]
}
After seeing test_should_auto_convert_id
asserted that AutoField
instances were converted to graphene.ID
types, I looked up the graphene type definition and noticed that the serializer for graphene.ID
is str
. This might make sense for graphene, but I don’t think it makes sense for django-graphene, where most users will have integer primary keys from relational databases.
I was able to coerce the id to an int by explicitly marking the field type as an int:
class UserType(DjangoObjectType):
id = graphene.Int(source='pk')
is_current_user = graphene.Boolean()
I ended up subclassing DjangoObjectType
to make this customization for all of my Django Model nodes, but this won’t help other users who wish to keep their primary key type intact.
Would django-graphene
be open to a PR adding this directly to DjangoObjectType
?
Issue Analytics
- State:
- Created 6 years ago
- Reactions:8
- Comments:9 (3 by maintainers)
Top GitHub Comments
I beg to differ. It’s an int in Django, therefore I expect the frontend to get an int as well. Period. What I don’t expect: the fact that graphene-django assumes that my frontend state is managed with string ids (it is not).
@dperetti @codekiln in GraphQL all
ID
types are represented as strings: https://graphql.org/learn/schema/#scalar-typesgraphene-django has made the decision that Django ID’s should be mapped to the GraphQL concept of ID’s and I think that is the right decision. You can always work around it like @codekiln has by explicitly mapping the Django field to a graphene Int field: