File: types.md

package info (click to toggle)
strawberry-graphql-django 0.62.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,968 kB
  • sloc: python: 27,530; sh: 17; makefile: 16
file content (138 lines) | stat: -rw-r--r-- 4,518 bytes parent folder | download
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).