I have the following models:
class Publisher(models.Model):
name = models.CharField(max_length=30)
class Book(models.Model):
title = models.CharField(max_length=100)
publisher = models.ForeignKey(Publisher)
In my views.py, When I want to show the publisher page, I also want to show their books, so I usually do something like this:
publisher = Publisher.objects.prefetch_related('book_set').filter(pk=id).first()
Then, after some processing I also do some work with the books
for book in publisher.book_set.all():
foo()
This works great, but I have one problem. If there is a book added between the query and the for loop, the publisher.book_set.all()
won't have the newly added books because it was prefetched.
Is there a way to update the publisher object?
select_related() “follows” foreign-key relationships, selecting additional related-object data when it executes its query. prefetch_related() does a separate lookup for each relationship and does the “joining” in Python.
Django offers a QuerySet method called select_related() that allows you to retrieve related objects for one-to-many relationships. This translates to a single, more complex QuerySet, but you avoid additional queries when accessing the related objects. The select_related method is for ForeignKey and OneToOne fields.
This is because a Django QuerySet is a lazy object. It contains all of the information it needs to populate itself from the database, but will not actually do so until the information is needed.
You can delete the entire prefetch cache on the instance:
if hasattr(publisher, '_prefetched_objects_cache'):
del publisher._prefetched_objects_cache
If you only want to delete a particular prefetched relation:
if hasattr(publisher, '_prefetched_objects_cache'):
publisher._prefetched_objects_cache.pop('book_set', None)
Also there is possibility to drop all prefetch_related
from Django doc:
To clear any prefetch_related behavior, pass None as a parameter::
non_prefetched = qs.prefetch_related(None)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With