|
@@ -336,13 +336,21 @@ class PageQuerySet(SearchableQuerySetMixin, TreeQuerySet):
|
|
|
for page in self.live():
|
|
|
page.unpublish()
|
|
|
|
|
|
- def specific(self):
|
|
|
+ def specific(self, defer=False):
|
|
|
"""
|
|
|
This efficiently gets all the specific pages for the queryset, using
|
|
|
the minimum number of queries.
|
|
|
+
|
|
|
+ When the "defer" keyword argument is set to True, only the basic page
|
|
|
+ fields will be loaded and all specific fields will be deferred. It
|
|
|
+ will still generate a query for each page type though (this may be
|
|
|
+ improved to generate only a single query in a future release).
|
|
|
"""
|
|
|
clone = self._clone()
|
|
|
- clone._iterable_class = SpecificIterable
|
|
|
+ if defer:
|
|
|
+ clone._iterable_class = DeferredSpecificIterable
|
|
|
+ else:
|
|
|
+ clone._iterable_class = SpecificIterable
|
|
|
return clone
|
|
|
|
|
|
def in_site(self, site):
|
|
@@ -352,7 +360,7 @@ class PageQuerySet(SearchableQuerySetMixin, TreeQuerySet):
|
|
|
return self.descendant_of(site.root_page, inclusive=True)
|
|
|
|
|
|
|
|
|
-def specific_iterator(qs):
|
|
|
+def specific_iterator(qs, defer=False):
|
|
|
"""
|
|
|
This efficiently iterates all the specific pages in a queryset, using
|
|
|
the minimum number of queries.
|
|
@@ -375,6 +383,13 @@ def specific_iterator(qs):
|
|
|
# model (i.e. Page) if the more specific one is missing
|
|
|
model = content_types[content_type].model_class() or qs.model
|
|
|
pages = model.objects.filter(pk__in=pks)
|
|
|
+
|
|
|
+ if defer:
|
|
|
+ # Defer all specific fields
|
|
|
+ from wagtail.core.models import Page
|
|
|
+ fields = [field.attname for field in Page._meta.get_fields() if field.concrete]
|
|
|
+ pages = pages.only(*fields)
|
|
|
+
|
|
|
pages_by_type[content_type] = {page.pk: page for page in pages}
|
|
|
|
|
|
# Yield all of the pages, in the order they occurred in the original query.
|
|
@@ -385,3 +400,8 @@ def specific_iterator(qs):
|
|
|
class SpecificIterable(BaseIterable):
|
|
|
def __iter__(self):
|
|
|
return specific_iterator(self.queryset)
|
|
|
+
|
|
|
+
|
|
|
+class DeferredSpecificIterable(BaseIterable):
|
|
|
+ def __iter__(self):
|
|
|
+ return specific_iterator(self.queryset, defer=True)
|