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.

DjangoObjectType Generates Wrong Schema on Arrayfield

See original GitHub issue

Description

Get wrong result for python manage.py graphql_schema. Here’s an example repo which can make it more clear: https://github.com/helloqiu/graphene_bug_example

If I define the model as followed:

from django.db import models
from django.contrib.postgres.fields import ArrayField


class Example(models.Model):
    simple_array = ArrayField(models.CharField(max_length=255))

and write the schema like this:

from graphene_django import DjangoObjectType
import graphene

from graphene_bug_example.models import Example as ExampleModel


class Example(DjangoObjectType):
    required_field = graphene.String(required=True)

    class Meta:
        model = ExampleModel


class Query(graphene.ObjectType):
    examples = graphene.List(Example)

schema = graphene.Schema(query=Query)

then run python manage.py graphql_schema, the String in simpleArray, which is an ArrayField, is nullable:

...
            {
              "name": "simpleArray",
              "description": "",
              "args": [],
              "type": {
                "kind": "NON_NULL",
                "name": null,
                "ofType": {
                  "kind": "LIST",
                  "name": null,
                  "ofType": {
                    "kind": "SCALAR",
                    "name": "String",
                    "ofType": null
                  }
                }
              },
              "isDeprecated": false,
              "deprecationReason": null
            },
...

Possible Solution

@convert_django_field.register(ArrayField)
def convert_postgres_array_to_list(field, registry=None):
    base_type = convert_django_field(field.base_field)
    if not isinstance(base_type, (List, NonNull)):
        base_type = type(base_type)
    return List(base_type, description=field.help_text, required=not field.null)

https://github.com/graphql-python/graphene-django/blob/master/graphene_django/converter.py#L212 I think we should restore required parameter after base_type = type(base_type). Something like this:

...
    if not isinstance(base_type, (List, NonNull)):
        base_type = type(base_type) if not base_type.kwargs['required'] else NonNull(type(base_type))
...

Maybe I will create a PR if this is verified as a bug by the maintainer.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:3
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
helloqiucommented, Oct 24, 2018

Can’t wait to make a PR. 😃

0reactions
Archiveccommented, Jul 4, 2022

Same issue exists for DjangoFormMutation with postgres SimpleArrayField as a form field. The generated schema results in a string.

from django.contrib.postgres.forms import SimpleArrayField


class SampleForm(forms.Form):
    array_string = SimpleArrayField(forms.CharField(max_length=128))

class SampleMutation(DjangoFormMutation):
    output = String()
    
    @classmethod
    def perform_mutate(cls, form, info):
        ...
input SampleMutationInput {
    arrayString: String!
}

Solution

Similar to OP’s solution for model field, but instead uses graphene_django.forms.converter to register the form field.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Graphene Documentation - Read the Docs
Create cookbook/schema.py and type the following: # cookbook/schema.py import graphene from graphene_django import DjangoObjectType.
Read more >
Queries & ObjectTypes - Graphene-Python
Graphene-Django ships with a special DjangoObjectType that automatically transforms a Django Model into a ObjectType for you. Full example¶. # my_app/schema.py ...
Read more >
Graphene using auto-generated type instead of defined ...
class PrimaryGroupType(DjangoObjectType): users = graphene. ... type is instead created Auto generated Type for SchedulePrimaryGroup model .
Read more >
[Answered]-How to use DRF serializers with Graphene-django
Consider we have model Subject. Let's create CRUD api for it. from graphene.types.scalars import Scalar class ObjectField(Scalar): # to serialize error message ...
Read more >
Python Examples of graphene.NonNull - ProgramCreek.com
def type(self): from .types import DjangoObjectType _type = super(ConnectionField, self).type non_null = False if isinstance(_type, NonNull): _type ...
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