3 Adding counts to DjangoFilterConnectionField
luto edited this page 2020-01-07 00:24:12 +01:00

DjangoFilterConnectionField() can be tricky to work with in cases where you wish to extend your schema. Fortunately, the solution is simple.

The trick here is to subclass Connection and declare a connection_class on your node type. In your Query declarations, DjangoFilterConnectionField will use that declared connection_class class seamlessly wherever it's defined.

You can now easily implement counts (or really anything) on your extended Connection class and use them in your queries, while retaining the built-in filtering that comes with DjangoFilterConnectionField:

from graphene import ObjectType, Connection, Node, Int
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from ..models import Place


class ExtendedConnection(Connection):
    class Meta:
        abstract = True

    total_count = Int()
    edge_count = Int()

    def resolve_total_count(root, info, **kwargs):
        return root.length
    def resolve_edge_count(root, info, **kwargs):
        return len(root.edges)


class PlaceType(DjangoObjectType):
    class Meta:
        model = Place
        filter_fields = {
            'id':  ['exact', 'icontains'],
            'name': ['exact', 'icontains', 'istartswith', 'iendswith'],
        }
        interfaces = (Node, )
        connection_class = ExtendedConnection


class Query(ObjectType):
    places = DjangoFilterConnectionField(PlaceType)

This allows, on this example schema, querying:

{
  places(first: 2, name_Icontains: "Dallas", after: "YXJyYXljb25uZWN0aW9uOjE1") {
    totalCount
    edgeCount
    edges {
      cursor
      node {
        id
        name
      }
    }
  }
}

Which returns:

{
  "data": {
    "places": {
      "totalCount": 23,
      "edgeCount": 2,
      "edges": [
        {
          "cursor": "YXJyYXljb25uZWN0aW9uOjE2",
          "node": {
            "id": "UGxhY2VUeXBlOjUxOA==",
            "name": "Dallas, Dallas, Texas, United States"
          }
        },
        {
          "cursor": "YXJyYXljb25uZWN0aW9uOjE3",
          "node": {
            "id": "UGxhY2VUeXBlOjU0Nw==",
            "name": "Election Precinct 4 Valley Creek, Dallas, Alabama, United States"
          }
        }
      ]
    }
  }
}