django: how to prefetch related for a model instance. perhaps by wrapping in a queryset?

  • Last Update :
  • Techknowledgy :

Prefetches the given lookups on an iterable of model instances. This is useful in code that receives a list of model instances as opposed to a QuerySet; for example, when fetching models from a cache or instantiating them manually.

Pass an iterable of model instances (must all be of the same class) and the lookups or Prefetch objects you want to prefetch for. For example:

>>> from django.db.models
import prefetch_related_objects
   >>>
   restaurants = fetch_top_restaurants_from_cache() # A list of Restaurants >>>
   prefetch_related_objects(restaurants, 'pizzas__toppings')

Since it takes an iterable, you can wrap your instance in a list:

prefetch_related_objects([profile], "relevant_attribute_1", "relevant_attribute_2")

Suggestion : 2

I use Django rest framework and I have anycodings_query-optimization decent nesting in my model relations.,I'm wondering if there's a better way to do anycodings_query-optimization this.,Since it takes an iterable, you can wrap anycodings_django-rest-framework your instance in a list:,An easy fix (and one that would generalize anycodings_query-optimization beyond serializers) would be if I can have a anycodings_query-optimization wrapper function to wrap my instance in a anycodings_query-optimization queryset and then call prefetch on that, anycodings_query-optimization passing it into the serializer.

I'm working on optimizing my queries. Many anycodings_query-optimization of my functions consume or manipulate a anycodings_query-optimization single instance of model and it's often anycodings_query-optimization further downstream in the data flow that it anycodings_query-optimization turns out I need some prefetching. One anycodings_query-optimization classic instance of this is with DRF anycodings_query-optimization serializers. Here's an example.

@api_view(['GET'])
def fetch_user_profile(request):
   profile = request.user.profile # has many nested relationships

return Response(UserProfileSerializer(profile).data, status = status.HTTP_200_OK) # this ends up taking many queries

Something like:

def queryset_wrap(instance):
   return type(instance).objects.filter(id = instance.id)

Prefetches the given lookups on an anycodings_django-rest-framework iterable of model instances. This is anycodings_django-rest-framework useful in code that receives a list of anycodings_django-rest-framework model instances as opposed to a anycodings_django-rest-framework QuerySet; for example, when fetching anycodings_django-rest-framework models from a cache or instantiating anycodings_django-rest-framework them manually.

Pass an iterable of model instances anycodings_django-rest-framework (must all be of the same class) and the anycodings_django-rest-framework lookups or Prefetch objects you want to anycodings_django-rest-framework prefetch for. For example:

>>> from django.db.models
import prefetch_related_objects
   >>>
   restaurants = fetch_top_restaurants_from_cache() # A list of Restaurants >>>
   prefetch_related_objects(restaurants, 'pizzas__toppings')

Since it takes an iterable, you can wrap anycodings_django-rest-framework your instance in a list:

prefetch_related_objects([profile], "relevant_attribute_1", "relevant_attribute_2")

Suggestion : 3

Prefetches the given lookups on an iterable of model instances. This is useful in code that receives a list of model instances as opposed to a QuerySet; for example, when fetching models from a cache or instantiating them manually.,Pass an iterable of model instances (must all be of the same class) and the lookups or Prefetch objects you want to prefetch for. For example:,How to sorted the list of model instance by number of an other related model in django REST?,Django: How to prefetch related for a model instance. Perhaps by wrapping in a queryset?

Prefetches the given lookups on an iterable of model instances. This is useful in code that receives a list of model instances as opposed to a QuerySet; for example, when fetching models from a cache or instantiating them manually.

Pass an iterable of model instances (must all be of the same class) and the lookups or Prefetch objects you want to prefetch for. For example:

>>> from django.db.models
import prefetch_related_objects
   >>>
   restaurants = fetch_top_restaurants_from_cache() # A list of Restaurants >>>
   prefetch_related_objects(restaurants, 'pizzas__toppings')

Since it takes an iterable, you can wrap your instance in a list:

prefetch_related_objects([profile], "relevant_attribute_1", "relevant_attribute_2")

Suggestion : 4

When Django encounters an instance of F(), it overrides the standard Python operators to create an encapsulated SQL expression; in this case, one which instructs the database to increment the database field represented by reporter.stories_filed.,Instead, Django uses the F() object to generate an SQL expression that describes the required operation at the database level.,Although reporter.stories_filed = F('stories_filed') + 1 looks like a normal Python assignment of value to an instance attribute, in fact it’s an SQL construct describing an operation on the database.,Tells Django which value should be returned when the expression is used to apply a function over an empty result set. Defaults to NotImplemented which forces the expression to be computed on the database.

from django.db.models
import Count, F, Value
from django.db.models.functions
import Length, Upper
from django.db.models.lookups
import GreaterThan

# Find companies that have more employees than chairs.
Company.objects.filter(num_employees__gt = F('num_chairs'))

# Find companies that have at least twice as many employees
# as chairs.Both the querysets below are equivalent.
Company.objects.filter(num_employees__gt = F('num_chairs') * 2)
Company.objects.filter(
   num_employees__gt = F('num_chairs') + F('num_chairs'))

# How many chairs are needed
for each company to seat all employees ?
   >>>
   company = Company.objects.filter(
      ...num_employees__gt = F('num_chairs')).annotate(
      ...chairs_needed = F('num_employees') - F('num_chairs')).first() >>>
   company.num_employees
120
   >>>
   company.num_chairs
50
   >>>
   company.chairs_needed
70

# Create a new company using expressions. >>>
   company = Company.objects.create(name = 'Google', ticker = Upper(Value('goog')))
# Be sure to refresh it
if you need to access the field. >>>
   company.refresh_from_db() >>>
   company.ticker 'GOOG'

# Annotate models with an aggregated value.Both forms
# below are equivalent.
Company.objects.annotate(num_products = Count('products'))
Company.objects.annotate(num_products = Count(F('products')))

# Aggregates can contain complex computations also
Company.objects.annotate(num_offerings = Count(F('products') + F('services')))

# Expressions can also be used in order_by(), either directly
Company.objects.order_by(Length('name').asc())
Company.objects.order_by(Length('name').desc())
# or using the double underscore lookup syntax.
from django.db.models
import CharField
from django.db.models.functions
import Length
CharField.register_lookup(Length)
Company.objects.order_by('name__length')

# Boolean expression can be used directly in filters.
from django.db.models
import Exists
Company.objects.filter(
   Exists(Employee.objects.filter(company = OuterRef('pk'), salary__gt = 10))
)

# Lookup expressions can also be used directly in filters
Company.objects.filter(GreaterThan(F('num_employees'), F('num_chairs')))
# or annotations.
Company.objects.annotate(
   need_chairs = GreaterThan(F('num_employees'), F('num_chairs')),
)
# Tintin filed a news story!
   reporter = Reporters.objects.get(name = 'Tintin')
reporter.stories_filed += 1
reporter.save()
from django.db.models
import F

reporter = Reporters.objects.get(name = 'Tintin')
reporter.stories_filed = F('stories_filed') + 1
reporter.save()
reporter = Reporters.objects.get(pk = reporter.pk)
# Or, more succinctly:
   reporter.refresh_from_db()
reporter = Reporters.objects.filter(name = 'Tintin')
reporter.update(stories_filed = F('stories_filed') + 1)
Reporter.objects.update(stories_filed = F('stories_filed') + 1)