Fields customisation

To add a non-database field to the GraphQL object representation of a model, a special arguments have to be specified on a wagtail_graphql.models.GraphQLField instance.

class wagtail_graphql.models.GraphQLField(name, resolve_func=None, graphql_type=None)

Bases: object

Specify metadata about a model field that is to be registered at a GraphQL object type.

Parameters:
  • name – Name of the field.
  • resolve_func (callable) – A custom resolve function that will be used to resolve data for this field.
  • graphql_type – Graphene type that will be used by that field.

The name of the field can be custom as long as it does not interfere with other field names on the object.

The custom GraphQL type returned by the field can be specified using graphql_type parameter, e.g.

from wagtail_graphql.models import GraphQLField

GraphQLField('settings', graphql_type=graphene.JSONString)

However if there is no corresponding database field of that name, the field will not be accessible. To allow that resolve_func must be specified. The argument must be a Graphene-compatible resolver.

import json

import graphene
from wagtail_graphql.models import GraphQLField

GraphQLField('settings', graphql_type=graphene.Field(graphene.JSONString)),
             resolve_func=lambda self, info: json.loads(
                 self.settings
             ))

Model object types

Sometimes it may be necessary to use a Django model as an object type for a custom non-database field. To refer to an automatically generated object a special utility function has to be used that will resolve the object type lazily - wagtail_graphql.lazy_model_type().

 # locations/models.py
 from django.db import models

 from wagtail_graphql import lazy_model_type
 from wagtail_graphql.models import GraphQLEnabledModel, GraphQLField


 class Country(GraphQLEnabledModel, models.Model):
     # Fields about a country


 class LocationPage(GraphQLEnabledModel, Page):
     lat_long = models.CharField()

     graphql_fields = [
         GraphQLField('country',
                     graphql_type=graphene.Field(
                         lazy_model_type('locations.Country')
                     ),
                     resolve_func=lambda self, info: self.get_country()),
     ]

     def get_country(self):
         # Logic to get a country object based on latitude and longitude.
         return country

QuerySetList

wagtail_graphql.types.structures.QuerySetList is a custom list type that adds Django’s QuerySet arguments like filtering or ordering. However to specify it on the model classes it is necessary to import it lazily using wagtail_graphql.lazy_queryset_list(). To benefit from the arguments built-in in the QuerySetList, the queryset has to be filtered through wagtail_graphql.utils.get_base_queryset_for_model_or_qs() or if it is a page wagtail_graphql.utils.get_base_queryset_for_page_model_or_qs() must be used.

 # locations/models.py
 from django.db import models

 from wagtail_graphql import lazy_queryset_list
 from wagtail_graphql.models import GraphQLEnabledModel, GraphQLField


 def resolve_locations(self, info, **kwargs):
     from wagtail_graphql.utils import get_base_queryset_for_page_model_or_qs

     return get_base_queryset_for_page_model_or_qs(
         self.get_location_pages(), info, **kwargs
     )


 class Country(GraphQLEnabledModel, models.Model):
     # Fields about a country

     graphql_fields = [
         GraphQLField('locations', graphql_type=graphene.Field(
             lazy_queryset_list('locations.LocationPage')
         ), resolve_func=resolve_locations)
     ]

     def get_location_pages(self):
         location_pages_queryset = LocationPage.objects.all()
         # Filter the queryset
         return location_pages_queryset


 class LocationPage(GraphQLEnabledModel, Page):
     # Fields about a location