Identity Map Usage¶
The
django_prefetch_utils.identity_map.prefetch_related_objects()
implementation use an identity map to provide a
number of benefits over Django’s default. See
Comparison with default implementation for a discussion of the
improvements. It should be a drop-in replacement, requiring no changes
of user code.
Using the identity map globally¶
The easiest way to use the identity map implementation is to set the
PREFETCH_UTILS_DEFAULT_IMPLEMENTATION setting:
PREFETCH_UTILS_DEFAULT_IMPLEMENTATION = (
'django_prefetch_utils.identity_map.prefetch_related_objects'
)
This will make it so that all calls to
django.db.models.query.prefetch_related_objects will use the
identity map implementation.
If at any point you which to use Django’s default implementation, you can use
the use_original_prefetch_related_objects()
context decorator:
from from django_prefetch_utils.selector import use_original_prefetch_related_objects
@use_original_prefetch_related_objects()
def some_function():
return Dog.objects.prefetch_related("toys")[0] # uses default impl.
Using the identity map locally¶
The
use_prefetch_identity_map()
context decorator can be used if you want to use identity map
implementation without using it globally:
@use_prefetch_identity_map()
def some_function():
return Dog.objects.prefetch_related('toys')[0] # uses identity map impl.
Persisting the identity map across calls¶
There may be times where you want to use the same identity map across
different calls to prefetch_related_objects. In that case, you
can use the
use_persistent_prefetch_identity_map():
def some_function():
with use_persistent_prefetch_identity_map() as identity_map:
dogs = list(Dogs.objects.prefetch_related("toys"))
with use_persistent_prefetch_identity_map(identity_map):
# No queries are done here since all of the toys
# have been fetched and stored in *identity_map*
prefetch_related_objects(dogs, "favorite_toy")
It can also be used as a decorator:
@use_persistent_prefetch_identity_map()
def some_function():
dogs = list(Dogs.objects.prefetch_related("toys"))
# The toy.dog instances will be identical (not just equal)
# to the ones fetched on the line above
toys = list(Toy.objects.prefetch_related("dog"))
...
@use_persistent_prefetch_identity_map(pass_identity_map=True)
def some_function(identity_map):
dogs = list(Dogs.objects.prefetch_related("toys"))
toys = list(Toy.objects.prefetch_related("dog"))
...
Note that when
use_persistent_prefetch_identity_map()
is active, then QuerySet._fetch_all will be monkey-patched so that any
objects fetched will be added to / checked against the identity map.