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_cacheafter 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.Modelbasewith 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¶
-
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_querysetmethod.Return type: django.db.models.QuerySet
-
-
class
GenericPrefetchRelatedDescriptorManager(descriptor, instance)[source]¶ A
django.db.models.Managerto be used in conjunction withRelatedQuerySetDescriptor.-
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.
-
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, thenget_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_querysetmethod.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_listtuple containing the annotated value oncache_nameon the object.-
cache_name¶ Returns the name of the attribute where we will cache the annotated value. We are overriding
cache_namefromGenericPrefetchRelatedDescriptorso 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
-
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
QuerySetwhich 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()andget_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_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_relation()[source]¶ returns the string which specifies how to associate a parent model to a child.
for example, if the parent were
common.models.userand the child wereservices.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
querysetfor 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]¶
-
class
TopChildDescriptorFromFieldBase[source]¶ A subclass of
TopChildDescriptorfor 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 implementget_child_field().
-
class
TopChildDescriptorFromGenericRelation(generic_relation, order_by)[source]¶ For further customization,
-
class
TopChildDescriptorFromGenericRelationBase[source]¶ A subclass of
TopChildDescriptorfor use when the children are described by adjango.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_parent_relation()[source]¶ Returns the name of the field on the child corresponding to the object primary key.
Return type: str
-
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
QuerySetwhich 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
-