Graphene-django: DjangoConnectionField and DjangoFilterConnectionField does not support NonNull connections

Created on 4 Jan 2019  路  6Comments  路  Source: graphql-python/graphene-django

Connections fields shouldn't be nullable. I'm generating client side types through graphql introspection and have to do additional existence checking for connections. DjangoConnectionField and DjangoFilterConnectionField should default to creating NonNull connections

Most helpful comment

I've created a custom connection class just for that purpose and use it successfully across the entire project. We use Apollo's codegen + Typescript in our client apps and with these connections we have much cleaner types:

class NonNullConnection(Connection):

    class Meta:
        abstract = True

    @classmethod
    def __init_subclass_with_meta__(cls, node=None, name=None, **options):
        super().__init_subclass_with_meta__(node=node, name=name, **options)

        # Override the original EdgeBase type to make to `node` field required.
        class EdgeBase:
            node = Field(
                cls._meta.node, description='The item at the end of the edge',
                required=True)
            cursor = String(
                required=True, description='A cursor for use in pagination')

        # Create the edge type using the new EdgeBase.
        edge_name = cls.Edge._meta.name
        edge_bases = (EdgeBase, ObjectType,)
        edge = type(edge_name, edge_bases, {})
        cls.Edge = edge

        # Override the `edges` field to make it non-null list
        # of non-null edges.
        cls._meta.fields['edges'] = Field(NonNull(List(NonNull(cls.Edge))))

All 6 comments

I've created a custom connection class just for that purpose and use it successfully across the entire project. We use Apollo's codegen + Typescript in our client apps and with these connections we have much cleaner types:

class NonNullConnection(Connection):

    class Meta:
        abstract = True

    @classmethod
    def __init_subclass_with_meta__(cls, node=None, name=None, **options):
        super().__init_subclass_with_meta__(node=node, name=name, **options)

        # Override the original EdgeBase type to make to `node` field required.
        class EdgeBase:
            node = Field(
                cls._meta.node, description='The item at the end of the edge',
                required=True)
            cursor = String(
                required=True, description='A cursor for use in pagination')

        # Create the edge type using the new EdgeBase.
        edge_name = cls.Edge._meta.name
        edge_bases = (EdgeBase, ObjectType,)
        edge = type(edge_name, edge_bases, {})
        cls.Edge = edge

        # Override the `edges` field to make it non-null list
        # of non-null edges.
        cls._meta.fields['edges'] = Field(NonNull(List(NonNull(cls.Edge))))

@maarcingebala this works well for making the edges and the cursor nonnull but not for the top level connection. The connection itself is still nullable

@mvanlonden if you wan't make connection required itself:

all_persons = relay.ConnectionField(PersonConnection, required=True)

ConnectionField extends Field and you can pass required.

@smmoosavi awesome! thanks

I think you can close #567

I think this should be opened. Solution not working starting from version 2

Was this page helpful?
0 / 5 - 0 ratings