---
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.Fruit, 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).
