Decorators ========== Grapple exposes a few fields for the root schema such as ``pages``, ``images``, ``documents``, ``media`` and ``redirects``. Here are some useful decorators that allow you to expand your GraphQL schema further: @register_query_field --------------------- .. module:: grapple.helpers .. class:: register_query_field(field_name, plural_field_name=None, query_params=None, required=False, plural_required=False, plural_item_required=False, middleware=None) You can easily expose any Django model from your codebase by adding the ``@register_query_field`` decorator like so: .. code-block:: python from grapple.helpers import register_query_field @register_query_field('advert') class Advert(models.Model): url = models.URLField(null=True, blank=True) text = models.CharField(max_length=255) panels = [FieldPanel("url"), FieldPanel("text")] graphql_fields = [GraphQLString("url"), GraphQLString("text")] def __str__(self): return self.text You can now query your adverts with the following query: :: { # Get all adverts adverts { url text } # Get a specific advert advert(id: 1) { url text } } You can add custom query parameters like so: .. code-block:: python @register_query_field('advert', 'adverts', { "id": graphene.Int(), "url": graphene.String(), }) and then use it in your queries: :: { # Get a specific advert advert(url: "some-unique-url") { url text } } You can make the singular query return type required like so: .. code-block:: python @register_query_field('advert', required=True) and then should look like this on your schema: :: advert(id: Int): Advert! instead of: :: advert(id: Int): Advert You can can also make the plural query return list type required: .. code-block:: python @register_query_field('advert', plural_required=True) making the plural query look like this on your schema: :: adverts(id: Int, ...): [Advert]! instead of the default: :: adverts(id: Int, ...): [Advert] If you want to make the plural query return list item type required: .. code-block:: python @register_query_field('advert', plural_item_required=True) making the plural query look like this: :: adverts(id: Int, ...): [Advert!] instead of the default: :: adverts(id: Int, ...): [Advert] You can add middleware to the queries generated by the ``register_query_field`` decorator: .. code-block:: python from grapple.middleware import IsAuthenticatedMiddleware @register_query_field('advert', middleware=[IsAuthenticatedMiddleware]) More information can be found on :doc:`middleware docs `. @register_paginated_query_field ------------------------------- .. module:: grapple.helpers .. class:: register_paginated_query_field(field_name, plural_field_name=None, query_params=None, required=False, plural_required=False, plural_item_required=False, middleware=None) You can easily expose any Django model from your codebase by adding the ``@register_paginated_query_field`` decorator like so: .. code-block:: python from grapple.helpers import register_paginated_query_field @register_paginated_query_field('advert') class Advert(models.Model): url = models.URLField(null=True, blank=True) text = models.CharField(max_length=255) panels = [FieldPanel("url"), FieldPanel("text")] graphql_fields = [GraphQLString("url"), GraphQLString("text")] def __str__(self): return self.text You can now query your adverts with the following query: :: { # Get adverts paginated adverts(page: 1, perPage: 10) { items { url text } pagination { total count perPage currentPage prevPage nextPage totalPages } } # Get a specific advert advert(id: 1) { url text } } The default ``per_page`` value is 10 and can be changed with the ``GRAPPLE["PAGE_SIZE"]`` setting. The ``per_page`` has a maximum value of 100 by default and can be changed with the ``GRAPPLE["MAX_PAGE_SIZE"]`` setting. .. code-block:: python # settings.py GRAPPLE = { # ... "PAGE_SIZE": 10, "MAX_PAGE_SIZE": 100, } You can add custom query parameters like so: .. code-block:: python @register_paginated_query_field('advert', 'adverts', { "id": graphene.Int(), "url": graphene.String(), }) and then use it in your queries: :: { # Get a specific advert advert(url: "some-unique-url") { url text } } You can make the singular query return type required like so: .. code-block:: python @register_paginated_query_field('advert', required=True) and then should look like this on your schema: :: advert(id: Int): Advert! instead of: :: advert(id: Int): Advert You can can also make the plural query return list type required: .. code-block:: python @register_paginated_query_field('advert', plural_required=True) making the plural query look like this on your schema: :: adverts(page: Int, perPage: Int, ...): AdvertPaginatedType! Type AdvertPaginatedType { items: [Advert]! pagination: PaginationType! } instead of the default: :: adverts(page: Int, perPage: Int, ...): AdvertPaginatedType Type AdvertPaginatedType { items: [Advert] pagination: PaginationType } If you want to make the plural query return list item type required: .. code-block:: python @register_paginated_query_field('advert', plural_item_required=True) making the plural query look like this: :: adverts(page: Int, perPage: Int, ...): AdvertPaginatedType Type AdvertPaginatedType { items: [Advert!] pagination: PaginationType } instead of the default: :: adverts(page: Int, perPage: Int, ...): AdvertPaginatedType Type AdvertPaginatedType { items: [Advert] pagination: PaginationType } You can add middleware to the queries generated by the ``register_paginated_query_field`` decorator: .. code-block:: python from grapple.middleware import IsAuthenticatedMiddleware @register_paginated_query_field('advert', middleware=[IsAuthenticatedMiddleware]) More information can be found on :doc:`middleware docs `. @register_singular_query_field ------------------------------- .. module:: grapple.helpers .. class:: register_singular_query_field(field_name, query_params=None, required=False, middleware=None) Returns the first item of the given type using the ``Model`` ordering. You can expose any Django model by decorating it with ``@register_singular_query_field``. This is especially useful when you have Wagtail Pages with ``max_count`` of one(`Ref: Wagtail documentation `_), thus there is no need to query by id. .. code-block:: python from grapple.helpers import register_singular_query_field @register_singular_query_field('first_advert') class Advert(models.Model): url = models.URLField(null=True, blank=True) text = models.CharField(max_length=255) panels = [FieldPanel("url"), FieldPanel("text")] graphql_fields = [GraphQLString("url"), GraphQLString("text")] def __str__(self): return self.text and then use it in your queries: :: { # Get the first advert firstAdvert { url text } } If you have multiple items, you could change the order: :: { # Get the first advert firstAdvert(order: "-id") { url text } } You can add middleware to the queries generated by the ``register_singular_query_field`` decorator: .. code-block:: python from grapple.middleware import IsAuthenticatedMiddleware @register_singular_query_field('first_advert', middleware=[IsAuthenticatedMiddleware]) More information can be found on :doc:`middleware docs `.