Django fetch modes¶
Django 6.1 adds QuerySet.fetch_mode() to control reads of unloaded foreign keys,
one-to-one relations, deferred columns and generic relations. FETCH_ONE is
the default. FETCH_PEERS batches missing values for instances from the same
queryset; FETCH_RAISE raises FieldFetchBlocked instead of reading implicitly.
Related-manager queries are not themselves batched by this mechanism. See
Django's reference.
Configuration¶
AIODRF = {
"FETCH_MODE": "raise", # None (unchanged), "peers", or "raise"
}
Generic views apply this mode on Django versions that provide it. On older
supported versions the setting cannot enforce fetch modes; it is not a backport.
For endpoint-specific selection, keep the global setting at None and use
Django's public API:
from django.db import models
queryset = Book.objects.select_related("author").fetch_mode(models.FETCH_RAISE)
An explicit global mode can override a mode already selected on the queryset. Choose one place for the application's policy.
Execution boundary¶
Fetch modes do not change the database driver. Missing-field access can still
perform synchronous I/O. FETCH_PEERS does not make inline representation safe:
load known relations explicitly and keep lazy representation in a worker.
Use FETCH_RAISE in tests to expose unintended reads.
Meta.auto_prefetch is a separate optional optimizer under
aiodrf.contrib.builtin.prefetch. It derives explicit loading paths from serializer
fields; fetch modes govern later implicit access. Neither replaces authorization.