# Documentation Django 6.0.7

# Fetch modes

New in Django 6.1.

When accessing model fields that were not loaded as part of the original query, Django will fetch that field’s data from the database. You can customize the behavior of this fetching with a fetch mode, making it more efficient or even blocking it.

Use `QuerySet.fetch_mode()` to set the fetch mode for model instances fetched by a `QuerySet`:

    from django.db import models

    books = Book.objects.fetch_mode(models.FETCH_PEERS)

Fetch modes apply to:

- `ForeignKey` fields

- `OneToOneField` fields and their reverse accessors

- Fields deferred with `QuerySet.defer()` or `QuerySet.only()`

- Relations génériques

Django copies the fetch mode of an instance to any related objects it fetches, so the mode applies to a whole tree of relationships, not just the top-level model in the initial `QuerySet`. This copying is also done in related managers, even though fetch modes don’t affect such managers” queries.

## Available modes

Referencing fetch modes

Fetch modes are defined in `django.db.models.fetch_modes`, but for convenience they’re imported into `django.db.models`. The standard convention is to use `from django.db import models` and refer to the fetch modes as `models.<mode>`.

Django provides three fetch modes. We’ll explain them below using these models:

    from django.db import models

    class Author(models.Model): ...

    class Book(models.Model):
        author = models.ForeignKey(Author, on_delete=models.CASCADE)
        ...

…and this loop:

    for book in books:
        print(book.author.name)

…where `books` is a `QuerySet` of `Book` instances using some fetch mode.

FETCH_ONE

Fetches the missing field for the current instance only. This is the default mode.

Using `FETCH_ONE` for the above example would use:

- 1 query to fetch `books`

- N queries, where N is the number of books, to fetch the missing `author` field

…for a total of 1+N queries. This query pattern is known as the « N+1 queries problem » because it often leads to performance issues when N is large.

FETCH_PEERS

Fetches the missing field for the current instance and its « peers »—instances that came from the same initial `QuerySet`. The behavior of this mode is based on the assumption that if you need a field for one instance, you probably need it for all instances in the same batch, since you’ll likely process them all identically.

Using `FETCH_PEERS` for the above example would use:

- 1 query to fetch `books`

- 1 query to fetch all missing `author` fields for the batch of books

…for a total of 2 queries. The batch query makes this mode a lot more efficient than `FETCH_ONE` and is similar to an on-demand call to `QuerySet.prefetch_related()` or `prefetch_related_objects()`. Using `FETCH_PEERS` can reduce most cases of the « N+1 queries problem » to two queries without much effort.

The « peer » instances are tracked in a list of weak references, to avoid memory leaks where some peer instances are discarded.

FETCH_RAISE

Raises a `FieldFetchBlocked` exception.

Using `FETCH_RAISE` for the above example would raise an exception at the access of `book.author`, like:

    FieldFetchBlocked("Fetching of Primary.value blocked.")

This mode can prevent unintentional queries in performance-critical sections of code.

## Make a fetch mode the default for a model class

Set the default fetch mode for a model class with a custom manager that overrides `get_queryset()`:

    from django.db import models

    class BookManager(models.Manager):
        def get_queryset(self):
            return super().get_queryset().fetch_mode(models.FETCH_PEERS)

    class Book(models.Model):
        title = models.TextField()
        author = models.ForeignKey("Author", on_delete=models.CASCADE)

        objects = BookManager()