### Install strawberry-graphql-django Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/index.md Installs the strawberry-graphql-django package and optionally django-choices-field using poetry or pip. ```shell poetry add strawberry-graphql-django poetry add django-choices-field # Not required but recommended ``` ```shell pip install strawberry-graphql-django ``` -------------------------------- ### Install Project Dependencies with Poetry Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/README.md Installs project dependencies using Poetry, a dependency management tool. This is part of the development setup process. ```shell $ git clone https://github.com/strawberry-graphql/strawberry-django $ cd strawberry-django $ python -m pip install poetry $ make install ``` -------------------------------- ### Install and Configure Daphne for ASGI Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/subscriptions.md Instructions for installing the Daphne ASGI server and configuring Django's `settings.py` to use it. This includes adding 'daphne' to `INSTALLED_APPS` and setting the `ASGI_APPLICATION` variable to point to the ASGI application defined in `asgi.py`. ```bash pip install daphne ``` ```python # settings.py ... INSTALLED_APPS = [ ... 'daphne', 'django.contrib.staticfiles', ... ] ... ASGI_APPLICATION = 'MyProject.asgi.application' ... ``` -------------------------------- ### Prefix Explanation Example (Python) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/legacy-ordering.md An example demonstrating how the `prefix` argument is used in custom order methods, specifically when ordering a nested relationship like `color.name` for a `Fruit` object. ```python from typing import Any @strawberry_django.order(models.Fruit) class FruitOrder: name: auto color: ColorOrder | None @strawberry_django.order(models.Color) class ColorOrder: @strawberry_django.order_field def name(self, value: Any, prefix: str): # prefix is "fruit_set__" if unused root object is ordered instead if value: return ["name"] return [] ``` -------------------------------- ### Install strawberry-graphql-django Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/README.md Installs the strawberry-graphql-django package using pip. This is the first step to integrating Strawberry GraphQL with a Django project. ```shell pip install strawberry-graphql-django ``` -------------------------------- ### Run Django Migrations Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/index.md Applies database migrations to create the defined models in your Django project. ```shell python manage.py makemigrations python manage.py migrate ``` -------------------------------- ### Install Pre-commit Hook Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/README.md Installs the pre-commit hook to enforce code quality standards before commits. This command sets up the git hook for the project. ```shell pre-commit install ``` -------------------------------- ### Setup GraphQL Schema with Authentication Mutations in Python Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/authentication.md Sets up the GraphQL schema with query and mutation types for authentication. It includes a 'me' query to get the current user and mutations for 'login', 'logout', and 'register'. The register mutation uses the UserInput type for input validation. ```python import strawberry import strawberry_django from .types import User, UserInput @strawberry.type class Query: me: User = strawberry_django.auth.current_user() @strawberry.type class Mutation: login: User = strawberry_django.auth.login() logout = strawberry_django.auth.logout() register: User = strawberry_django.auth.register(UserInput) ``` -------------------------------- ### Build GraphQL Schema and Queries - schema.py Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/index.md Assembles the GraphQL schema using strawberry, defining root queries and integrating DjangoOptimizerExtension for performance. ```python import strawberry from strawberry_django.optimizer import DjangoOptimizerExtension from .types import Fruit @strawberry.type class Query: fruits: list[Fruit] = strawberry_django.field() schema = strawberry.Schema( query=Query, extensions=[ DjangoOptimizerExtension, ], ) ``` -------------------------------- ### Query Example with Ordering (GraphQL) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/legacy-ordering.md A GraphQL query demonstrating how to use the defined ordering inputs, specifically ordering fruits by the name of their associated color in ascending order. ```graphql { fruits( order: {color: name: ASC} ) { ... } } ``` -------------------------------- ### Strawberry Django Cursor Connection Implementation Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/relay.md Demonstrates the usage of DjangoCursorConnection for efficient pagination with Django QuerySets. It includes a basic connection setup and a custom resolver example. ```python @strawberry.type class Query: fruit: DjangoCursorConnection[FruitType] = strawberry_django.connection() @strawberry_django.connection(DjangoCursorConnection[FruitType]) def fruit_with_custom_resolver(self) -> list[Fruit]: return Fruit.objects.all() ``` -------------------------------- ### Field-level Pagination Setup (Python) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/pagination.md Shows an alternative way to enable pagination by applying it directly to the 'fruits' field instead of the type, resulting in the same schema. ```python import strawberry import strawberry_django from . import models from typing import auto @strawberry_django.type(models.Fruit) class Fruit: name: auto @strawberry.type class Query: fruits: list[Fruit] = strawberry_django.field(pagination=True) ``` -------------------------------- ### Example GraphQL Query for Nested Ordering Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/ordering.md This snippet shows a GraphQL query example demonstrating how to apply nested ordering. It specifies ordering by `color.name` in ascending order for a list of fruits. ```graphql { fruits( ordering: [{color: name: ASC}] ) { ... } } ``` -------------------------------- ### GraphQL: Example Filter Query with Nested Filtering Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/filters.md An example GraphQL query demonstrating how to use the `filters` argument with nested filtering, specifically filtering `fruits` by `color.name`. ```graphql { fruits( filters: {color: name: "blue"} ) { ... } } ``` -------------------------------- ### List-based Filtering Query Example - GraphQL Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/filters.md Provides a GraphQL query example showcasing the use of list-based AND filters to combine multiple conditions on the 'name' field. ```graphql { vegetables( filters: { AND: [{ name: { contains: "blue" } }, { name: { contains: "squash" } }] } ) { id } } ``` -------------------------------- ### OffsetPaginated Generic Setup (Python) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/pagination.md Demonstrates using the OffsetPaginated generic for more complex pagination needs. This wraps results in an object containing pagination info and total count. ```python from strawberry_django.pagination import OffsetPaginated import strawberry import strawberry_django from . import models from typing import auto @strawberry_django.type(models.Fruit) class Fruit: name: auto @strawberry.type class Query: fruits: OffsetPaginated[Fruit] = strawberry_django.offset_paginated() ``` -------------------------------- ### Subscription Response Example Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/subscriptions.md Illustrates the expected JSON response format from the 'count' subscription when executed with a target of 10. The response shows the final value received from the subscription. ```json { "data": { "count": 9 } } ``` -------------------------------- ### Default Pagination Setup (Python) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/pagination.md Sets up basic limit/offset pagination for a Fruit type in Strawberry Django. It defines a Fruit type with a 'name' field and a Query type with a 'fruits' field that utilizes default pagination. ```python import strawberry import strawberry_django from . import models from typing import auto @strawberry_django.type(models.Fruit, pagination=True) class Fruit: name: auto @strawberry.type class Query: fruits: list[Fruit] = strawberry_django.field() ``` -------------------------------- ### Execute Subscription Query Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/subscriptions.md An example GraphQL query to test the 'count' subscription. It specifies a target of 10, and the server will return incremental counts every 0.5 seconds until the target is reached. ```graphql subscription { count(target: 10) } ``` -------------------------------- ### Django Models for Optimization Example Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/optimizer.md Defines Django models `Artist`, `Album`, and `Song` to illustrate how the query optimizer works with related data. These models represent a typical relational structure. ```python from django.db import models class Artist(models.Model): name = models.CharField() class Album(models.Model): name = models.CharField() release_date = models.DateTimeField() artist = models.ForeignKey("Artist", related_name="albums") class Song(models.Model): name = models.CharField() duration = models.DecimalField() album = models.ForeignKey("Album", related_name="songs") ``` -------------------------------- ### Define Model for Optimization Hints (Python) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/optimizer.md Example of a Django model with a calculated property that can be optimized by Strawberry Django. This property ('total') calculates the sum of price and quantity. ```Python from django.db import models import decimal class OrderItem(models.Model): price = models.DecimalField() quantity = models.IntegerField() @property def total(self) -> decimal.Decimal: return self.price * self.quantity ``` -------------------------------- ### Create GraphQL Types from Django Models - types.py Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/index.md Defines GraphQL types for Django models using strawberry_django.type, automatically inferring fields and handling relations. ```python import strawberry_django from strawberry import auto from . import models @strawberry_django.type(models.Fruit) class Fruit: id: auto name: auto category: auto color: "Color" # Strawberry will understand that this refers to the "Color" type that's defined below @strawberry_django.type(models.Color) class Color: id: auto name: auto fruits: list[Fruit] # This tells strawberry about the ForeignKey to the Fruit model and how to represent the Fruit instances on that relation ``` -------------------------------- ### Define Django Models with Relations - models.py Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/index.md Defines Django models for Fruit and Color, including a ForeignKey relation and using TextChoicesField for automatic enum mapping in GraphQL. ```python from django.db import models from django_choices_field import TextChoicesField class FruitCategory(models.TextChoices): CITRUS = "citrus", "Citrus" BERRY = "berry", "Berry" class Fruit(models.Model): """A tasty treat""" name = models.CharField(max_length=20, help_text="The name of the fruit variety") category = TextChoicesField(choices_enum=FruitCategory, help_text="The category of the fruit") color = models.ForeignKey( "Color", on_delete=models.CASCADE, related_name="fruits", blank=True, null=True, help_text="The color of this kind of fruit", ) class Color(models.Model): """The hue of your tasty treat""" name = models.CharField( max_length=20, help_text="The color name", ) ``` -------------------------------- ### Generated GraphQL Schema for Mutation (GraphQL) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/mutations.md This GraphQL schema is generated from the Python mutation example. It defines the `Fruit` type, the `CreateFruitPayload` union which can return either a `Fruit` object or `OperationInfo` for errors, and the mutation signature. ```graphql enum OperationMessageKind { INFO WARNING ERROR PERMISSION VALIDATION } type OperationInfo { """List of messages returned by the operation.""" messages: [OperationMessage!]! } type OperationMessage { """The kind of this message.""" kind: OperationMessageKind! """The error message.""" message: String! """ The field that caused the error, or `null` if it isn't associated with any particular field. """ field: String """The error code, or `null` if no error code was set.""" code: String } type Fruit { name: String! color: String! } union CreateFruitPayload = Fruit | OperationInfo mutation { createFruit( name: String! color: String! ): CreateFruitPayload! } ``` -------------------------------- ### Define a GraphQL Subscription in Strawberry Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/subscriptions.md Example of creating a basic GraphQL subscription resolver named 'count' using Strawberry. This subscription yields integers from 0 up to a target value with a delay between each yield, demonstrating asynchronous subscription behavior. ```python import asyncio import strawberry @strawberry.type class Subscription: @strawberry.subscription async def count(self, target: int = 100) -> int: for i in range(target): yield i await asyncio.sleep(0.5) ``` -------------------------------- ### Customizing Default Pagination Limit (Python) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/pagination.md Provides an example of how to define a custom OffsetPaginationInput subclass to change the default limit for pagination. This custom input can then be applied to types or fields. ```python import strawberry import strawberry_django from . import models from typing import auto @strawberry.input def MyOffsetPaginationInput(OffsetPaginationInput): limit: int = 250 # Pass it to the pagination argument when defining the type @strawberry_django.type(models.Fruit, pagination=MyOffsetPaginationInput) class Fruit: name: auto @strawberry.type class Query: # Or pass it to the pagination argument when defining the field fruits: list[Fruit] = strawberry_django.field(pagination=MyOffsetPaginationInput) ``` -------------------------------- ### Optimize Model Property with 'model_property' (Python) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/optimizer.md Example of using the `strawberry_django.model_property` decorator directly on a model's property to provide optimization hints. This allows the field to be resolved with `auto` in the GraphQL schema. ```Python import decimal from strawberry_django.descriptors import model_property from django.db import models class OrderItem(models.Model): price = models.DecimalField() quantity = models.IntegerField() @model_property(only=["price", "quantity"]) def total(self) -> decimal.Decimal: return self.price * self.quantity ``` -------------------------------- ### Basic Strawberry Django Type for Model (Python) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/optimizer.md A basic Strawberry Django type definition for the OrderItem model, using 'auto' for fields. This setup might lead to inefficient queries if not optimized. ```Python from strawberry import auto import strawberry_django from .models import OrderItem @strawberry_django.type(OrderItem) class OrderItem: price: auto quantity: auto total: auto ``` -------------------------------- ### Define Custom Order Methods for Fruit Model Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/ordering.md This example shows how to define custom ordering logic for the `FruitOrder` type using `@strawberry_django.order_field`. It includes custom resolvers for 'discovered_by' and 'order_number', demonstrating how to manipulate QuerySets and return custom ordering values. ```python from typing import List, Tuple from django.db.models import QuerySet, Count from strawberry.types import Info import strawberry import strawberry_django from django.db import models @strawberry_django.order_type(models.Fruit) class FruitOrder: name: auto @strawberry_django.order_field def discovered_by(self, value: bool, prefix: str) -> list[str]: if not value: return [] return [f"{prefix}discover_by__name", f"{prefix}name"] @strawberry_django.order_field def order_number( self, info: Info, queryset: QuerySet, value: strawberry_django.Ordering, # `auto` can be used instead prefix: str, ) -> tuple[QuerySet, list[str]] | list[str]: queryset = queryset.alias( _ordered_num=Count(f"{prefix}orders__id") ) ordering = value.resolve(f"{prefix}_ordered_num") return queryset, [ordering] ``` -------------------------------- ### Python: Define Custom Filter Methods with Strawberry Django Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/filters.md Demonstrates defining custom filter methods for Django models using Strawberry. Includes examples for simple string filtering, full name filtering with aliasing, and handling complex lookups with `process_filters`. Uses `strawberry_django.filter_field` decorator. ```python import strawberry from django.db.models import Q, QuerySet from django.db.models.functions import Concat from django.db.models import Value import strawberry_django from . import models from strawberry_django.fields.types import Info @strawberry_django.filter(models.Fruit) class FruitFilter: name: auto last_name: auto @strawberry_django.filter_field def simple(self, value: str, prefix) -> Q: return Q(**{f"{prefix}name": value}) @strawberry_django.filter_field def full_name( self, queryset: QuerySet, value: str, prefix: str ) -> tuple[QuerySet, Q]: queryset = queryset.alias( _fullname=Concat( f"{prefix}name", Value(" "), f"{prefix}last_name" ) ) return queryset, Q(**{"_fullname": value}) @strawberry_django.filter_field def full_name_lookups( self, info: Info, queryset: QuerySet, value: strawberry_django.FilterLookup[str], prefix: str ) -> tuple[QuerySet, Q]: queryset = queryset.alias( _fullname=Concat( f"{prefix}name", Value(" "), f"{prefix}last_name" ) ) return strawberry_django.process_filters( filters=value, queryset=queryset, info=info, prefix=f"{prefix}_fullname" ) ``` -------------------------------- ### Run Tests with Make Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/README.md Executes project tests using the 'make test' command. Makefiles are used to automate common development tasks like running tests. ```shell $ make test ``` -------------------------------- ### Configure ASGI Application in Django Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/subscriptions.md This snippet shows how to modify the `MyProject.asgi.py` file to integrate Strawberry GraphQL's AuthGraphQLProtocolTypeRouter with Django Channels, enabling WebSocket support for subscriptions. It requires specifying the Django settings module and the path to your Strawberry schema. ```python # MyProject.asgi.py import os from django.core.asgi import get_asgi_application from strawberry_django.routers import AuthGraphQLProtocolTypeRouter os.environ.setdefault("DJANGO_SETTINGS_MODULE", "MyProject.settings") # CHANGE the project name django_asgi_app = get_asgi_application() # Import your Strawberry schema after creating the django ASGI application # This ensures django.setup() has been called before any ORM models are imported # for the schema. from .schema import schema # CHANGE path to where you housed your schema file. application = AuthGraphQLProtocolTypeRouter( schema, django_application=django_asgi_app, ) ``` -------------------------------- ### Run Tests in Parallel Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/README.md Runs tests in parallel using the 'make test-dist' command, which can speed up the testing process on multi-core systems. ```shell $ make test-dist ``` -------------------------------- ### Relay Support with Strawberry Django Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/relay.md Demonstrates various ways to implement Relay connections using strawberry_django, including default relay, relay with total count, and custom resolvers. ```APIDOC ## Relay Support in Strawberry Django ### Description This section details how to integrate Relay specifications with Strawberry Django, showcasing different connection strategies and their behind-the-scenes operations. ### Usage Examples **Option 1: Default Relay without totalCount** ```python import strawberry import strawberry_django from strawberry_django.relay import DjangoListConnection # Assume Fruit model and FruitType are defined @strawberry.type class Query: fruit: strawberry.relay.ListConnection[FruitType] = strawberry_django.connection() ``` This is the default behavior, using `strawberry_django.connection()` for standard Relay connections. **Option 2: Relay with totalCount using DjangoListConnection** ```python import strawberry import strawberry_django from strawberry_django.relay import DjangoListConnection # Assume Fruit model and FruitType are defined @strawberry.type class Query: fruit_with_total_count: DjangoListConnection[FruitType] = strawberry_django.connection() ``` This option utilizes `DjangoListConnection` to include the `totalCount` in the connection payload. **Option 3: Custom Resolver for Relay Connection** ```python import strawberry import strawberry_django from strawberry_django.relay import DjangoListConnection # Assume Fruit model, FruitType, and SomeModel are defined @strawberry.type class Query: @strawberry_django.connection(DjangoListConnection[FruitType]) def fruit_with_custom_resolver(self) -> list[SomeModel]: return Fruit.objects.all() ``` Allows manual definition of resolvers for Relay connections, offering more control. ### Behind the Scenes Operations - Automatic resolution of `relay.NodeID` using the model's primary key. - Automatic generation of resolvers for connections without explicit definitions (e.g., `some_model_conn`). - Seamless integration of connection resolution with features like filters, ordering, and permissions. ### Customization Notes - Custom `relay.NodeID` fields or resolvers will not be overridden if defined manually. - Set `MAP_AUTO_ID_AS_GLOBAL_ID=True` in settings if primarily using `relay.Node` and `GlobalID` for object identification. ### DjangoCursorConnection **Description** `DjangoCursorConnection` provides cursor-based pagination for improved performance on large datasets compared to `ListConnection`'s slicing method. It uses range queries (e.g., `Q(due_date__gte=...)`) which are more efficient with database indexes. **Requirements** - Requires a strictly ordered `QuerySet` (no two entries considered equal by ordering). If ordering is ambiguous (e.g., `order_by('due_date')`), it automatically orders by the primary key as a fallback. - Cursors are not compatible between different orders if the order is user-configurable (e.g., via `@strawberry_django.order`). **Drawback** - Users cannot jump to a specific page directly. - Best suited for use cases like infinitely scrollable lists. **Usage Example** ```python import strawberry import strawberry_django from strawberry_django.relay import DjangoCursorConnection # Assume Fruit model and FruitType are defined @strawberry.type class Query: fruit: DjangoCursorConnection[FruitType] = strawberry_django.connection() @strawberry_django.connection(DjangoCursorConnection[FruitType]) def fruit_with_custom_resolver(self) -> list[Fruit]: return Fruit.objects.all() ``` ``` -------------------------------- ### Basic Ordering Schema (GraphQL) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/legacy-ordering.md The GraphQL schema generated from the basic Python ordering types, showing the `Ordering` enum and the input types for `ColorOrder` and `FruitOrder`. ```graphql enum Ordering { ASC ASC_NULLS_FIRST ASC_NULLS_LAST DESC DESC_NULLS_FIRST DESC_NULLS_LAST } input ColorOrder { name: Ordering } input FruitOrder { name: Ordering color: ColorOrder } ``` -------------------------------- ### Test API with TestClient (Python) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/unit-testing.md Demonstrates how to use Strawberry-Django's TestClient to query a GraphQL API, testing both unauthenticated and authenticated scenarios for a 'me' query. Requires a Django test environment with the 'db' fixture. ```python from strawberry_django.test.client import TestClient def test_me_unauthenticated(db): client = TestClient("/graphql") res = client.query(""" query TestQuery { me { pk email firstName lastName } } """) assert res.errors is None assert res.data == {"me": None} def test_me_authenticated(db): user = User.objects.create(...) client = TestClient("/graphql") with client.login(user): res = client.query(""" query TestQuery { me { pk email firstName lastName } } """) assert res.errors is None assert res.data == { "me": { "pk": user.pk, "email": user.email, "firstName": user.first_name, "lastName": user.last_name, }, } ``` -------------------------------- ### Toggle Null Value Handling in Ordering Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/ordering.md This example shows how to configure a custom order field to explicitly handle null values. By setting `order_none=True` in the `@strawberry_django.order_field` decorator, nulls will be considered during sorting. ```python @strawberry_django.order_field(order_none=True) ``` -------------------------------- ### Enable Autocompletion with Editors Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/faq.md This import statement resolves potential symbol and type resolution issues in editors like VSCode by explicitly importing the `strawberry.django` module. This is a common configuration step for improved developer experience. ```python import strawberry.django ``` -------------------------------- ### Querying with Default Pagination (GraphQL) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/pagination.md Demonstrates how to query the 'fruits' field using the pagination argument with specific offset and limit values. ```graphql query { fruits(pagination: { offset: 0, limit: 2 }) { name } } ``` -------------------------------- ### Enable Query Optimizer Extension in Schema Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/optimizer.md Demonstrates how to enable the `DjangoOptimizerExtension` in a Strawberry schema configuration. This is a prerequisite for the optimizer to function. ```python import strawberry from strawberry_django.optimizer import DjangoOptimizerExtension schema = strawberry.Schema( Query, extensions=[ # other extensions... DjangoOptimizerExtension, ] ) ``` -------------------------------- ### Querying with OffsetPaginated Generic (GraphQL) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/pagination.md Illustrates how to query fields using the OffsetPaginated generic, accessing total count, page info, and the results. ```graphql query { fruits(pagination: { offset: 0, limit: 2 }) { totalCount pageInfo { limit offset } results { name } } } ``` -------------------------------- ### Override Default Type Mapping for Django Fields Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/fields.md Provides an example of how to update the default mapping between Django field types and Strawberry types. This is useful for custom Django fields or when a different Strawberry type is desired. ```python from typing import NewType from django.db import models import strawberry import strawberry_django from strawberry_django.fields.types import field_type_map Slug = strawberry.scalar( NewType("Slug", str), serialize=lambda v: v, parse_value=lambda v: v, ) @strawberry.type class MyCustomFileType: ... field_type_map.update({ models.SlugField: Slug, models.FileField: MyCustomFileType, }) ``` -------------------------------- ### Customizing QuerySet Resolver with Pagination and Ordering Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/pagination.md Demonstrates how to define a custom resolver for pagination, allowing for queryset filtering and applying ordering. ```APIDOC ## GET /graphql ### Description Retrieves a paginated list of available fruits, with optional ordering applied. ### Method GET ### Endpoint /graphql ### Parameters #### Query Parameters - **onlyAvailable** (Boolean!) - Required - Filters fruits to include only available ones. Defaults to true. - **pagination** (OffsetPaginationInput) - Optional - Input for pagination, specifying offset and limit. - **offset** (Int) - Required - The starting index for the results. Defaults to 0. - **limit** (Int) - Optional - The maximum number of results to return. - **order** (FruitOrder) - Optional - Specifies the ordering for the results. - **name** (Ordering) - Orders by fruit name. - **price** (Ordering) - Orders by fruit price. ### Request Example ```graphql query { fruits(onlyAvailable: true, pagination: { offset: 0, limit: 5 }, order: { name: ASC }) { totalCount pageInfo { limit offset } results { name price } } } ``` ### Response #### Success Response (200) - **fruits** (FruitOffsetPaginated!) - An object containing paginated results. - **totalCount** (Int!) - The total number of items available, excluding pagination. - **pageInfo** (PaginationInfo!) - Information about the current page. - **limit** (Int!) - The limit used for this page. - **offset** (Int!) - The offset used for this page. - **results** ([Fruit]!) - The list of Fruit objects for the current page. - **name** (String!) - The name of the fruit. - **price** (Decimal!) - The price of the fruit. #### Response Example ```json { "data": { "fruits": { "totalCount": 8, "pageInfo": { "limit": 5, "offset": 0 }, "results": [ { "name": "Apple", "price": "1.00" }, { "name": "Banana", "price": "0.50" } ] } } } ``` ``` -------------------------------- ### Customize QuerySet with User-Based Filtering Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/types.md Shows an advanced example of customizing the `QuerySet` for a Strawberry type by using the `info` object to access the current user and apply conditional filtering, restricting access based on user roles. ```python from strawberry_django.auth.utils import get_current_user @strawberry_django.type(models.Fruit) class Berry: @classmethod def get_queryset(cls, queryset, info, **kwargs): user = get_current_user(info) if not user.is_staff: # Restrict access to top secret berries if the user is not a staff member queryset = queryset.filter(is_top_secret=False) return queryset.filter(name__contains="berry") ``` -------------------------------- ### Cursor Pagination (Relay Style) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/pagination.md Briefly introduces cursor-based pagination, also known as Relay-style pagination, and points to the Relay integration documentation for implementation details. ```APIDOC ## Cursor pagination (aka Relay style pagination) Strawberry Django supports cursor-based pagination, often referred to as Relay-style pagination, which is a common pattern for efficient pagination in GraphQL APIs. For detailed instructions and implementation guidance, refer to the [relay integration documentation](./relay.md). ``` -------------------------------- ### Override Default Order Method in Strawberry Django Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/legacy-ordering.md Demonstrates how to override the default 'order' method for resolving ordering of an entire object in Strawberry Django. It requires a 'queryset' argument and should likely use 'sequence'. The example shows aliasing the queryset and custom processing. ```python import strawberry import strawberry_django from django.db.models import Count from django.db.models.query import QuerySet from typing import Optional, Dict, List, Tuple from . import models @strawberry_django.order(models.Fruit) class FruitOrder: name: strawberry_django.auto @strawberry_django.order_field def ordered( self, info: strawberry.types.Info, queryset: QuerySet, value: strawberry_django.Ordering, prefix: str ) -> Tuple[QuerySet, List[str]] | List[str]: queryset = queryset.alias( _ordered_num=Count(f"{prefix}orders__id") ) return queryset, [value.resolve(f"{prefix}_ordered_num") ] @strawberry_django.order_field def order( self, info: strawberry.types.Info, queryset: QuerySet, prefix: str, sequence: Optional[Dict[str, strawberry_django.Ordering]] ) -> Tuple[QuerySet, List[str]]: queryset = queryset.filter( ... # Do some query modification ) return strawberry_django.process_order( self, info=info, queryset=queryset, sequence=sequence, prefix=prefix, skip_object_order_method=True ) ``` -------------------------------- ### Django Models for Project Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/optimizer.md Defines the Django model for a Project, including fields for topic, supervisor, and artist. This serves as the base for defining GraphQL types. ```python from django.db import models class Project(models.Model): topic = models.CharField(max_length=255) supervisor = models.CharField(max_length=30) artist = models.CharField(max_length=30) ``` -------------------------------- ### GraphQL Schema for Basic Ordering Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/ordering.md This snippet shows the GraphQL schema generated for the Python code defining `ColorOrder` and `FruitOrder`. It illustrates the enum `Ordering` and the input types with the `@oneOf` directive. ```graphql enum Ordering { ASC ASC_NULLS_FIRST ASC_NULLS_LAST DESC DESC_NULLS_FIRST DESC_NULLS_LAST } input ColorOrder @oneOf { name: Ordering } input FruitOrder @oneOf { name: Ordering color: ColorOrder } ``` -------------------------------- ### Export Schema using Strawberry Django Management Command Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/export-schema.md This command exports a GraphQL schema defined with strawberry_django to SDL format. It takes the schema location as a required argument and an optional output path. If the path is omitted, the schema is printed to the console. ```sh python manage.py export_schema --path ``` ```sh python manage.py export_schema myapp.schema --path=output/schema.graphql ``` -------------------------------- ### Overriding Default Order Method in Strawberry Django Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/ordering.md Demonstrates how to override the default `order` method in Strawberry Django to customize the ordering resolution for an entire object. It includes examples of defining custom order fields like `ordered` and `order`, showing how to modify the queryset and return the appropriate ordering information. ```python import strawberry from django.db.models import Count from strawberry.types import Info from strawberry_django import QuerySet import strawberry_django from . import models @strawberry_django.order_type(models.Fruit) class FruitOrder: name: auto @strawberry_django.order_field def ordered( self, info: Info, queryset: QuerySet, value: strawberry_django.Ordering, prefix: str ) -> tuple[QuerySet, list[str]] | list[str]: queryset = queryset.alias( _ordered_num=Count(f"{prefix}orders__id") ) return queryset, [value.resolve(f"{prefix}_ordered_num")] @strawberry_django.order_field def order( self, info: Info, queryset: QuerySet, prefix: str, ) -> tuple[QuerySet, list[str]]: queryset = queryset.filter( ... # Do some query modification ) return strawberry_django.ordering.process_ordering_default( self, info=info, queryset=queryset, prefix=prefix, ) ``` -------------------------------- ### Default Pagination with @strawberry_django.type Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/pagination.md Demonstrates how to enable default limit/offset pagination by setting `pagination=True` on a Strawberry Django type. ```APIDOC ## GET /graphql ### Description Retrieves a paginated list of fruits using default limit/offset pagination. ### Method GET ### Endpoint /graphql ### Parameters #### Query Parameters - **pagination** (OffsetPaginationInput) - Optional - Input for pagination, specifying offset and limit. - **offset** (Int) - Required - The starting index for the results. Defaults to 0. - **limit** (Int) - Optional - The maximum number of results to return. ### Request Example ```graphql query { fruits(pagination: { offset: 0, limit: 2 }) { name } } ``` ### Response #### Success Response (200) - **fruits** ([Fruit!]!) - A list of Fruit objects. - **name** (String!) - The name of the fruit. #### Response Example ```json { "data": { "fruits": [ { "name": "Apple" }, { "name": "Banana" } ] } } ``` ``` -------------------------------- ### Basic CUD Mutations with Strawberry Django Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/mutations.md Demonstrates the creation of basic CUD mutations (create, update, delete) for a Django model using strawberry-django. It showcases defining model types, input types, partial input types, and the mutation class itself. Dependencies include strawberry and strawberry_django. ```python from strawberry import auto from strawberry_django import mutations, NodeInput from strawberry.relay import Node @strawberry_django.type(SomeModel) class SomeModelType(Node): name: auto @strawberry_django.input(SomeModel) class SomeModelInput: name: auto @strawberry_django.partial(SomeModel) class SomeModelInputPartial(NodeInput): name: auto @strawberry.type class Mutation: create_model: SomeModelType = mutations.create(SomeModelInput) update_model: SomeModelType = mutations.update(SomeModelInputPartial) delete_model: SomeModelType = mutations.delete(NodeInput) ``` -------------------------------- ### Configure Strawberry Django Settings Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/settings.md This code snippet demonstrates how to configure the `STRAWBERRY_DJANGO` settings in a Django project's `settings.py` file. It enables features like fetching GraphQL field descriptions from Django's `help_text` and type descriptions from model docstrings, customizing mutation argument names and error handling, and mapping auto-generated IDs to `relay.GlobalID`. ```python STRAWBERRY_DJANGO = { "FIELD_DESCRIPTION_FROM_HELP_TEXT": True, "TYPE_DESCRIPTION_FROM_MODEL_DOCSTRING": True, "MUTATIONS_DEFAULT_ARGUMENT_NAME": "input", "MUTATIONS_DEFAULT_HANDLE_ERRORS": True, "GENERATE_ENUMS_FROM_CHOICES": False, "MAP_AUTO_ID_AS_GLOBAL_ID": True, "DEFAULT_PK_FIELD_NAME": "id", "PAGINATION_DEFAULT_LIMIT": 250, "ALLOW_MUTATIONS_WITHOUT_FILTERS": True, } ``` -------------------------------- ### Configure GraphQL URL Endpoint Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/README.md Configures the GraphQL endpoint in Django's `urls.py` using `AsyncGraphQLView`. This makes the GraphQL API accessible at the `/graphql` path. ```python from django.urls import include, path from strawberry.django.views import AsyncGraphQLView from .schema import schema urlpatterns = [ path('graphql', AsyncGraphQLView.as_view(schema=schema)), ] ``` -------------------------------- ### Custom Order Method: discovered_by (Python) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/legacy-ordering.md Demonstrates a custom order method `discovered_by` using `@strawberry_django.order_field`. This method returns a list of strings for field ordering based on a boolean input. ```python @strawberry_django.order(models.Fruit) class FruitOrder: name: auto @strawberry_django.order_field def discovered_by(self, value: bool, prefix: str) -> list[str]: if not value: return [] return [f"{prefix}discover_by__name", f"{prefix}name"] ``` -------------------------------- ### Enable Lookups for Fruit Filtering - Python Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/filters.md Shows how to enable lookups for the Fruit filter type, which adds more options for resolving each field. ```python @strawberry_django.filter_type(models.Fruit, lookups=True) class FruitFilter: id: auto name: auto ``` -------------------------------- ### Batch CUD Mutations Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/mutations.md Demonstrates how to perform multiple create, update, or delete operations atomically within a single mutation using batching. This approach enhances efficiency by grouping operations. The mutations accept and return lists of input and output types. Dependencies include strawberry and strawberry_django. ```python import strawberry from strawberry_django import mutations @strawberry.type class Mutation: createFruits: list[Fruit] = mutations.create(list[FruitPartialInput]) updateFruits: list[Fruit] = mutations.update(list[FruitPartialInput]) deleteFruits: list[Fruit] = mutations.delete(list[FruitPartialInput]) schema = strawberry.Schema(mutation=Mutation) ``` -------------------------------- ### Create Strawberry GraphQL Schema Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/README.md Creates a Strawberry GraphQL schema, defining the root Query type and including the `DjangoOptimizerExtension` for performance. The `fruits` query is exposed using `strawberry_django.field()`. ```python import strawberry import strawberry_django from strawberry_django.optimizer import DjangoOptimizerExtension from .types import Fruit @strawberry.type class Query: fruits: list[Fruit] = strawberry_django.field() schema = strawberry.Schema( query=Query, extensions=[ DjangoOptimizerExtension, # not required, but highly recommended ], ) ``` -------------------------------- ### Basic Ordering Types (Python) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/legacy-ordering.md Defines basic ordering types for Django models using `@strawberry_django.order`. The `auto` annotation simplifies the process, automatically wrapping fields in `Optional` and setting default values. ```python import strawberry import strawberry_django from django.db import models # Assuming models.Color and models.Fruit are defined elsewhere @strawberry_django.order(models.Color) class ColorOrder: name: auto @strawberry_django.order(models.Fruit) class FruitOrder: name: auto color: ColorOrder | None ``` -------------------------------- ### Define a Synchronous Resolver - Python Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/resolvers.md Demonstrates how to define a synchronous resolver for a Strawberry Django type. This resolver can be used in both ASGI/WSGI applications and will be automatically wrapped in `sync_to_async` if needed. ```python import strawberry_django from strawberry import auto from . import models @strawberry_django.type(models.Color) class Color: id: auto name: auto @strawberry_django.field def fruits(self) -> list[Fruit]: return self.fruits.objects.filter(...) ``` -------------------------------- ### Custom Queryset Resolver with Pagination (Python) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/pagination.md Demonstrates how to define a custom resolver for paginated fields. This allows for pre-filtering, ordering, and passing additional arguments to the queryset. ```python import strawberry import strawberry_django from django.db.models.query import QuerySet from . import models from typing import auto @strawberry_django.type(models.Fruit) class Fruit: name: auto price: auto @strawberry_django.order(models.Fruit) class FruitOrder: name: auto price: auto @strawberry.type class Query: @strawberry_django.offset_paginated(OffsetPaginated[Fruit], order=FruitOrder) def fruits(self, only_available: bool = True) -> QuerySet[Fruit]: queryset = models.Fruit.objects.all() if only_available: queryset = queryset.filter(available=True) return queryset ``` -------------------------------- ### Default Pagination Schema (GraphQL) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/pagination.md Illustrates the GraphQL schema generated for default pagination. It shows the Fruit type, the OffsetPaginationInput, and the Query type with the paginated 'fruits' field. ```graphql type Fruit { name: String! } input OffsetPaginationInput { offset: Int! = 0 limit: Int = null } type Query { fruits(pagination: OffsetPaginationInput): [Fruit!]! } ``` -------------------------------- ### Optimized ORM Query for Artist Data Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/optimizer.md Illustrates the Django ORM query generated by the optimizer when querying for artist data, including related albums and songs, and an annotation for the number of albums. It showcases `only`, `prefetch_related`, and `annotate`. ```python # For "artist" query Artist.objects.all().only("id", "name").prefetch_related( Prefetch( "albums", queryset=Album.objects.all().only("id", "name").prefetch_related( Prefetch( "songs", Song.objects.all().only("id", "name"), ) ) ), ).annotate( albums_count=Count("albums") ) ``` -------------------------------- ### Optimize Field with 'only' Hint (Python) Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/optimizer.md Demonstrates how to explicitly tell Strawberry Django's optimizer which fields are needed to resolve the 'total' field, preventing unnecessary queries for 'price' and 'quantity'. ```Python from strawberry import auto import strawberry_django from .models import OrderItem @strawberry_django.type(OrderItem) class OrderItem: price: auto quantity: auto total: auto = strawberry_django.field( only=["price", "quantity"], ) ``` -------------------------------- ### Customizing Default Pagination Limit Source: https://github.com/strawberry-graphql/strawberry-django/blob/main/docs/guide/pagination.md Explains how to customize the default pagination limit globally via settings or per-field using a custom input type. ```APIDOC ## GET /graphql ### Description Retrieves a paginated list of fruits with a customized default limit (e.g., 250). ### Method GET ### Endpoint /graphql ### Parameters #### Query Parameters - **pagination** (MyOffsetPaginationInput) - Optional - Input for pagination, specifying offset and limit. - **offset** (Int) - Required - The starting index for the results. Defaults to 0. - **limit** (Int) - Optional - The maximum number of results to return. Defaults to 250 if not provided. ### Request Example ```graphql query { fruits(pagination: { offset: 0, limit: 10 }) { name } } ``` ### Response #### Success Response (200) - **fruits** ([Fruit!]!) - A list of Fruit objects. - **name** (String!) - The name of the fruit. #### Response Example ```json { "data": { "fruits": [ { "name": "Apple" }, { "name": "Banana" } ] } } ``` ```