Django,在 prefetch_related 之后更新对象
Django, update the object after a prefetch_related
我有以下型号:
class Publisher(models.Model):
name = models.CharField(max_length=30)
class Book(models.Model):
title = models.CharField(max_length=100)
publisher = models.ForeignKey(Publisher)
在我的views.py中,当我想展示出版商的页面时,我也想展示他们的书,所以我通常会这样做:
publisher = Publisher.objects.prefetch_related('book_set').filter(pk=id).first()
然后,经过一些处理,我也对书籍进行了一些处理
for book in publisher.book_set.all():
foo()
效果很好,但我有一个问题。如果在查询和 for 循环之间添加了一本书,publisher.book_set.all()
将不会有新添加的书,因为它已被预取。
有没有办法更新发布者对象?
您可以删除实例上的整个预取缓存:
if hasattr(publisher, '_prefetched_objects_cache'):
del publisher._prefetched_objects_cache
如果您只想删除特定的预取关系:
if hasattr(publisher, '_prefetched_objects_cache'):
publisher._prefetched_objects_cache.pop('book_set', None)
也有可能从 Django doc 中删除所有 prefetch_related
:
To clear any prefetch_related behavior, pass None as a parameter::
non_prefetched = qs.prefetch_related(None)
有一个更好的方法来清除预取属性,仅使用 public Django API,即 refresh_from_db()
method:
# Reloads all fields from the object as well as clearing prefetched attributes
publisher.refresh_from_db()
# Clears one prefetched attribute, will be re-fetched on next access
publisher.refresh_from_db(fields=['book_set'])
for book in publisher.book_set.all():
我有以下型号:
class Publisher(models.Model):
name = models.CharField(max_length=30)
class Book(models.Model):
title = models.CharField(max_length=100)
publisher = models.ForeignKey(Publisher)
在我的views.py中,当我想展示出版商的页面时,我也想展示他们的书,所以我通常会这样做:
publisher = Publisher.objects.prefetch_related('book_set').filter(pk=id).first()
然后,经过一些处理,我也对书籍进行了一些处理
for book in publisher.book_set.all():
foo()
效果很好,但我有一个问题。如果在查询和 for 循环之间添加了一本书,publisher.book_set.all()
将不会有新添加的书,因为它已被预取。
有没有办法更新发布者对象?
您可以删除实例上的整个预取缓存:
if hasattr(publisher, '_prefetched_objects_cache'):
del publisher._prefetched_objects_cache
如果您只想删除特定的预取关系:
if hasattr(publisher, '_prefetched_objects_cache'):
publisher._prefetched_objects_cache.pop('book_set', None)
也有可能从 Django doc 中删除所有 prefetch_related
:
To clear any prefetch_related behavior, pass None as a parameter::
non_prefetched = qs.prefetch_related(None)
有一个更好的方法来清除预取属性,仅使用 public Django API,即 refresh_from_db()
method:
# Reloads all fields from the object as well as clearing prefetched attributes
publisher.refresh_from_db()
# Clears one prefetched attribute, will be re-fetched on next access
publisher.refresh_from_db(fields=['book_set'])
for book in publisher.book_set.all():