django_prefetch_utils.descriptors

This module is provides a number of classes to help writing descriptors which play nicely with Django’s prefetch_related system. A general guide to descriptors can be found in the Python documentation.

Base

class GenericPrefetchRelatedDescriptor[source]
cache_name

Returns the dictionary key where the associated queryset will be stored on instance._prefetched_objects_cache after prefetching.

Return type:str
contribute_to_class(cls, name)[source]

Sets the name of the descriptor and sets itself as an attribute on the class with the same name.

This method is called by Django’s django.db.models.base.Modelbase with the class the descriptor is defined on as well as the name it is being set up.

Returns:None
filter_queryset_for_instances(queryset, instances)[source]

Given a queryset for the related objects, returns that queryset filtered down to the ones related to instance.

Returns:a queryset
get_join_value_for_instance(instance)[source]

Returns the value used to associate instance with its related objects.

Parameters:instance – an instance of model

Returns the value used to associate rel_obj with its related instance.

Parameters:rel_obj – a related object
get_prefetch_model_class()[source]

Returns the model class of the objects that are prefetched by this descriptor.

Returns:subclass of django.db.models.Model
get_queryset(queryset=None)[source]

Returns the default queryset to use for the related objects.

The purpose of taking the optional queryset parameter is so that a custom queryset can be passed in as part of the prefetching process, and any subclasses can apply their own filters to that.

Parameters:queryset (QuerySet) – an optional queryset to use instead of the default queryset for the model
Return type:django.db.models.QuerySet
manager_class

alias of GenericPrefetchRelatedDescriptorManager

update_queryset_for_prefetching(queryset)[source]

Returns queryset updated with any additional changes needed when it is used as a queryset within get_prefetch_queryset.

Parameters:queryset (QuerySet) – the queryset which will be returned as part of the get_prefetch_queryset method.
Return type:django.db.models.QuerySet
class GenericPrefetchRelatedDescriptorManager(descriptor, instance)[source]

A django.db.models.Manager to be used in conjunction with RelatedQuerySetDescriptor.

cache_name

Returns the name used to store the prefetched related objects.

Return type:str
get_prefetch_queryset(instances, queryset=None)[source]

This is the primary method used by Django’s prefetch system to get all of the objects related to instances.

Parameters:
  • instances (list) – a list of instances of the class where this descriptor appears
  • queryset – an optional queryset
Returns:

the 5-tuple needed by Django’s prefetch system.

get_queryset()[source]

Returns a queryset of objects related to instance. This method checks to see if the queryset has been cached in instance._prefetched_objects_cache.

Return type:django.db.models.QuerySet

Via Lookup

class RelatedQuerySetDescriptorViaLookup(prefetch_model, lookup)[source]

This provides a descriptor for access to related objects where the relationship between the instances on which this descriptor is defined and the related objects can be specified by a Django “lookup”:

>>> class Author(models.Model):
...    pass
...
>>> class Book(models.Model):
...    authors = models.ManyToManyField(Author, related_name='books')
...
>>> class Reader(models.Model):
...     books_read = models.ManyToManyField(Book, related_name='read_by')
...     authors_read = RelatedQuerySetDescriptorViaLookupBase(
...         Author, 'books__read_by'
...     )
...
>>> reader = Reader.objects.prefetch_related('authors_read').first()
>>> reader.authors_read.count()  # no queries
42

The lookup specifies the path from the related object to the model on which the descriptor is defined.

get_prefetch_model_class()[source]

Returns the model class of the objects that are prefetched by this descriptor.

Returns:subclass of django.db.models.Model
lookup

Returns the Django lookup string which describes the relationship from the related object to the one on which this descriptor is defined.

Return type:str
class RelatedQuerySetDescriptorViaLookupBase[source]

This is a base class for descriptors which provide access to related objects where the relationship between the instances on which this descriptor is defined and the related objects can by specified by a Django “lookup” which specifies the path from the related object to the model on which the descriptor is defined.

filter_queryset_for_instances(queryset, instances)[source]

Returns queryset filtered to the objects which are related to instances. If queryset is None, then get_queryset() will be used instead.

Parameters:
  • instances (list) – instances of the class on which this descriptor is found
  • queryset (QuerySet) – the queryset to filter for instances
Return type:

django.db.models.QuerySet

get_join_value_for_instance(instance)[source]

Returns the value used to join the instance with the related object. In this case, it is the primary key of the instance.

Return type:int

Returns the value used to join the related_obj with the original instance. In this case, it is the primary key of the instance.

Return type:int
lookup

Returns the Django lookup string which describes the relationship from the related object to the one on which this descriptor is defined.

Return type:str
obj_pk_annotation

Returns the name of an annotation to be used on the queryset so that we can easily get the primary key for the original object without having to instantiate any intermediary objects.

Return type:str
update_queryset_for_prefetching(queryset)[source]

Returns an updated queryset for use in get_prefetch_queryset.

We need to add an annotation to the queryset so that know which related model to associate with which original instance.

Parameters:queryset (QuerySet) – the queryset which will be returned as part of the get_prefetch_queryset method.
Return type:django.db.models.QuerySet
class RelatedSingleObjectDescriptorViaLookup(prefetch_model, lookup)[source]

This provides a descriptor for access to a related object where the relationship to the instances on which this descriptor is defined and the related objects can be specified by a Django “lookup”:

>>> class Author(models.Model):
...    pass
...
>>> class Book(models.Model):
...    authors = models.ManyToManyField(Author, related_name='books')
...
>>> class Reader(models.Model):
...     books_read = models.ManyToManyField(Book, related_name='read_by')
...     some_read_author = RelatedSingleObjectDescriptorViaLookup(
...         Author, 'books__read_by'
...     )
...
>>> reader = Reader.objects.prefetch_related('some_read_author').first()
>>> reader.some_read_author  # no queries
<Author: Jane>

The lookup specifies the path from the related object to the model on which the descriptor is defined.

Annotation

class AnnotationDescriptor(annotation)[source]

This descriptor behaves like an annotated value would appear on a model. It lets you turn an annotation into a prefetch at the cost of an additional query:

>>> class Author(models.Model):
...    book_count = AnnotationDescriptor(Count('books'))
...
authors.models.Author
>>> author = Author.objects.get(name="Jane")
>>> author.book_count
11
>>> author = Author.objects.prefetch_related('book_count').get(name="Jane")
>>> author.book_count  # no queries done
11

It works by storing a values_list tuple containing the annotated value on cache_name on the object.

cache_name

Returns the name of the attribute where we will cache the annotated value. We are overriding cache_name from GenericPrefetchRelatedDescriptor so that we can just return the annotated value from __get__.

Return type:str
filter_queryset_for_instances(queryset, instances)[source]

Returns queryset filtered to the objects which are related to instances.

Parameters:
  • instances (list) – instances of the class on which this descriptor is found
  • queryset (QuerySet) – the queryset to filter for instances
Return type:

django.db.models.QuerySet

get_join_value_for_instance(instance)[source]

Returns the value used to associate instance with its related objects.

Parameters:instance – an instance of model

Returns the value used to associate rel_obj with its related instance.

Parameters:rel_obj – a related object
get_prefetch_model_class()[source]

Returns the model class of the objects that are prefetched by this descriptor.

Returns:subclass of django.db.models.model

Top Child

class TopChildDescriptor[source]

An abstract class for creating prefetchable descriptors which correspond to the top child in a group of children associated to a parent model.

For example, consider a descriptor for the most recent message in a conversation. In this case, the children would be the messages, and the parent would be the conversation. The ordering used to determine the “top child” would be -added.

filter_queryset_for_instances(queryset, instances)[source]

Returns a QuerySet which returns the top children for each of the parents in instances.

Note

This does not filter the set of child models which are included in the “consideration set”. To do that, please override get_child_filter_args() and get_child_filter_kwargs().

Parameters:
  • queryset (QuerySet) – the queryset of child objects to filter for instances
  • instances (list) – a list of the parent models whose children we want to fetch.
Return type:

django.db.models.QuerySet

get_child_filter_args()[source]

returns a tuple of all of the argument filters which should be used to filter the possible children returned.

Return type:tuple
get_child_filter_kwargs(**kwargs)[source]

returns a dictionary of all of the keyword argument filters which should be used to filter the possible children returned.

Parameters:kwargs (dict) – any overrides for the default filter
Return type:dict
get_child_model()[source]

returns the model class for the children.

get_child_order_by()[source]

returns a tuple which will be used to place an ordering on the children so that we can return the “top” one.

Return type:tuple
get_join_value_for_instance(parent)[source]

Returns the value used to associate the parent with the child fetched during the prefetching process. In this case, it is the primary key of the parent.

Return type:int

Returns the value used to associate the child with the parent object. In this case, it is the primary key of the parent.

Return type:int
get_parent_model()[source]

returns the model class for the parents.

get_parent_relation()[source]

returns the string which specifies how to associate a parent model to a child.

for example, if the parent were common.models.user and the child were services.models.service, then this should be 'provider__user'.

Return type:str
get_prefetch_model_class()[source]

Returns the model class of the objects that are prefetched by this descriptor.

Returns:subclass of django.db.models.model
get_subquery()[source]

returns a queryset for all of the child models which should be considered.

Return type:queryset
get_top_child_pks(parent_pks)[source]

Returns a queryset for the primary keys of the top children for the parent models whose primary keys are in parent_pks.

Parameters:parent_pks (list) – a list of primary keys for the parent models whose children we want to fetch.
Return type:QuerySet
parent_pk_annotation

Returns the name of the attribute which will be annotated on child instances and will correspond to the primary key of the associated parent.

Return type:str
class TopChildDescriptorFromField(field, order_by)[source]
get_child_field()[source]

Returns the field on the child model which is a foreign key to the parent model.

Return type:django.db.models.fields.Field
get_child_order_by()[source]

returns a tuple which will be used to place an ordering on the children so that we can return the “top” one.

Return type:tuple
class TopChildDescriptorFromFieldBase[source]

A subclass of TopChildDescriptor for use when the children are related to the parent by a foreign key. In that case, anyone implementing a subclass of this only needs to implement get_child_field().

get_child_field()[source]

Returns the field on the child model which is a foreign key to the parent model.

Return type:django.db.models.fields.Field
get_child_model()[source]

returns the model class for the children.

get_parent_model()[source]

returns the model class for the parents.

get_parent_relation()[source]

returns the string which specifies how to associate a parent model to a child.

for example, if the parent were common.models.user and the child were services.models.service, then this should be 'provider__user'.

Return type:str
class TopChildDescriptorFromGenericRelation(generic_relation, order_by)[source]

For further customization,

get_child_field()[source]

Returns the generic relation on the parent model for the children.

Return type:django.contrib.contenttypes.fields.GenericRelation
get_child_order_by()[source]

returns a tuple which will be used to place an ordering on the children so that we can return the “top” one.

Return type:tuple
class TopChildDescriptorFromGenericRelationBase[source]

A subclass of TopChildDescriptor for use when the children are described by a django.contrib.contenttypes.fields.GenericRelation.

apply_content_type_filter(queryset)[source]

Filters the (child) queryset to only be those that correspond to content_type.

Return type:django.db.models.QuerySet
content_type

Returns the content type of the parent model.

get_child_field()[source]

Returns the generic relation on the parent model for the children.

Return type:django.contrib.contenttypes.fields.GenericRelation
get_child_model()[source]

Returns the Model class for the children.

get_parent_model()[source]

Returns the Model class for the parent.

get_parent_relation()[source]

Returns the name of the field on the child corresponding to the object primary key.

Return type:str
get_queryset(queryset=None)[source]

Returns a QuerySet which returns the top children for each of the parents who have primary keys in parent_pks.

Return type:django.db.models.QuerySet
get_subquery()[source]

Returns a QuerySet for all of the child models which should be considered.

Return type:django.db.models.QuerySet

Equal Fields

class EqualFieldsDescriptor(related_model, join_fields)[source]

A descriptor which provides a manager for objects which are related by having equal values for a series of columns:

>>> class Book(models.Model):
...     title = models.CharField(max_length=32)
...     published_year = models.IntegerField()
>>> class Author(models.Model):
...     birth_year = models.IntegerField()
...     birth_books = EqualFieldsDescriptor(Book, [('birth_year', 'published_year')])
...
>>> # Get the books published in the year the author was born
>>> author = Author.objects.prefetch_related('birth_books')
>>> author.birth_books.count()  # no queries are done here
10
filter_queryset_for_instances(queryset, instances)[source]

Returns a QuerySet which returns the top children for each of the parents in instances.

Parameters:queryset (QuerySet) – a queryset for the objects related to instances
Return type:django.db.models.QuerySet
get_join_value_for_instance(instance)[source]

Returns a tuple of the join values for instance.

Return type:tuple

Returns a tuple of the join values for rel_obj.

Return type:tuple
get_prefetch_model_class()[source]

Returns the model class of the objects that are prefetched by this descriptor.

Returns:subclass of django.db.models.model
preprocess_join_fields(join_fields)[source]
Returns:a list of _FieldMapping objects.