1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
---
title: Defining Types
---
# Defining Types
## Output types
> [!NOTE]
> It is highly recommended to enable the [Query Optimizer Extension](optimizer.md)
> for improved performance and avoid some common pitfalls (e.g. the `n+1` issue)
Output types are generated from models. The `auto` type is used for field type auto resolution.
Relational fields are described by referencing to other types generated from Django models.
A many-to-many relation is described with the `typing.List` type annotation.
`strawberry_django` will automatically generate resolvers for relational fields.
More information about that can be read from [resolvers](resolvers.md) page.
```python title="types.py"
import strawberry_django
from strawberry import auto
@strawberry_django.type(models.Fruit)
class Fruit:
id: auto
name: auto
color: "Color"
@strawberry_django.type(models.Color)
class Color:
id: auto
name: auto
fruits: list[Fruit]
```
## Input types
Input types can be generated from Django models using the `strawberry_django.input` decorator.
The first parameter is the model which the type is derived from.
```python title="types.py"
@strawberry_django.input(models.Fruit)
class FruitInput:
id: auto
name: auto
color: "ColorInput"
```
A partial input type, in which all `auto`-typed fields are optional, is generated by setting the `partial` keyword argument in `input` to `True`.
Partial input types can be generated from existing input types through class inheritance.
Non-`auto` type annotations will be respected—and therefore required—unless explicitly marked `Optional[]`.
```python title="types.py"
@strawberry_django.input(models.Color, partial=True)
class FruitPartialInput(FruitInput):
color: list["ColorPartialInput"]
# Auto fields are optional
@strawberry_django.input(models.Color, partial=True)
class ColorPartialInput:
id: auto
name: auto
fruits: list[FruitPartialInput]
# Alternate input; "name" field will be required
@strawberry_django.input(models.Color, partial=True)
class ColorNameRequiredPartialInput:
id: auto
name: str
fruits: list[FruitPartialInput]
```
## Types from Django models
Django models can be converted to `strawberry` Types with the `strawberry_django.type` decorator. Custom descriptions can be added using the `description` keyword argument (See: [`strawberry.type` decorator API](https://strawberry.rocks/docs/types/object-types#api)).
```python title="types.py"
import strawberry_django
@strawberry_django.type(models.Fruit, description="A tasty snack")
class Fruit:
...
```
### Adding fields to the type
By default, no fields are implemented on the new type. Check the documentation
on [How to define Fields](fields.md) for that.
### Customizing the returned `QuerySet`
> [!WARNING]
> By doing this you are modifying all automatic `QuerySet` generation for any field
> that returns this type. Ideally you will want to define your own [resolver](resolvers.md)
> instead, which gives you more control over it.
By default, a `strawberry_django` type will get data from the default manager for its Django Model.
You can implement a custom `get_queryset` classmethod to your type to do some extra processing to the default queryset,
like filtering it further.
```python title="types.py"
@strawberry_django.type(models.Fruit)
class Berry:
@classmethod
def get_queryset(cls, queryset, info, **kwargs):
return queryset.filter(name__contains="berry")
```
The `get_queryset` classmethod is given a `QuerySet` to filter and
a `strawberry` `Info` object containing details about the request.
You can use that `info` parameter to, for example,
limit access to results based on the current user in the request:
```python title="types.py"
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")
```
> [!NOTE]
> Another way of limiting this is by using the [PermissionExtension](permissions.md)
> provided by this lib.
The `kwargs` dictionary can include other parameters that were added in a `@strawberry.django.type` definition
like [filters](filters.md) or [pagination](pagination.md).
|