manager: reduce num of queries on page view (#69400)
gitea-wip/combo/pipeline/head Build started... Details
gitea/combo/pipeline/head Something is wrong with the build of this commit Details

This commit is contained in:
Lauréline Guérin 2022-09-21 16:49:05 +02:00
parent c2afb605e0
commit cf068ec94a
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
7 changed files with 43 additions and 16 deletions

View File

@ -33,6 +33,7 @@ from django.utils.translation import gettext_lazy as _
from django.utils.translation import pgettext_lazy
from requests.exceptions import RequestException
from combo import utils
from combo.data.library import register_cell_class
from combo.data.models import CellBase, Page
from combo.utils import NothingInCacheException, requests
@ -1144,13 +1145,8 @@ class WcsCardCell(CardMixin, CellBase):
# get cells with explicit ids
results = []
cells = (
WcsCardCell.objects.filter(page=self.page_id)
.exclude(pk=self.pk)
.exclude(slug='') # no slug
.filter(related_card_path='') # no explicit ids
.exclude(card_ids__contains=',') # multiple ids, can not follow relations
)
cells = WcsCardCell.get_cells_with_explicit_ids_by_page().get(self.page_id) or []
cells = [c for c in cells if c.pk != self.pk]
many_cells = len(cells) > 1
for cell in cells:
# follow relations
@ -1165,6 +1161,19 @@ class WcsCardCell(CardMixin, CellBase):
)
return results
@classmethod
@utils.cache_during_request
def get_cells_with_explicit_ids_by_page(cls):
result = collections.defaultdict(list)
cells = (
cls.objects.exclude(slug='') # no slug
.filter(related_card_path='') # no explicit ids
.exclude(card_ids__contains=',') # multiple ids, can not follow relations
).order_by('order')
for cell in cells:
result[cell.page_id].append(cell)
return result
def get_card_ids_from_related(self, context, request):
def get_relation(relations, varname, reverse):
for relation in relations:

View File

@ -928,14 +928,21 @@ class CellBase(models.Model, metaclass=CellMeta):
def cleaned_extra_css_class(self):
return ' '.join([x for x in self.extra_css_class.split() if not x.startswith('size--')])
@property
def asset_css_classes(self):
@classmethod
@utils.cache_during_request
def get_assets_by_key(cls):
from combo.apps.assets.models import Asset
return {a.key: a for a in Asset.objects.all()}
@property
def asset_css_classes(self):
if not hasattr(self, '_asset_keys'):
self._asset_keys = self.get_asset_slot_keys()
if not hasattr(self, '_assets'):
self._assets = {a.key: a for a in Asset.objects.filter(key__in=self._asset_keys.keys())}
all_assets = CellBase.get_assets_by_key()
self._assets = {key: all_assets.get(key) for key in self._asset_keys.keys()}
self._assets = {k: v for k, v in self._assets.items() if v}
if not self._asset_keys or not self._assets:
return ''
@ -1024,6 +1031,7 @@ class CellBase(models.Model, metaclass=CellMeta):
cell_filter=None,
skip_cell_cache=False,
prefetch_validity_info=False,
prefetch_groups=False,
select_related=None,
load_contenttypes=False,
cells_exclude=None,
@ -1066,6 +1074,8 @@ class CellBase(models.Model, metaclass=CellMeta):
cells_queryset = cells_queryset.exclude(cells_exclude)
if extra_filter:
cells_queryset = cells_queryset.filter(extra_filter)
if prefetch_groups:
cells_queryset = cells_queryset.prefetch_related('groups')
if select_related:
cells_queryset = cells_queryset.select_related(
*select_related.get('__all__', []), *select_related.get(klass.get_cell_type_str(), [])
@ -1079,6 +1089,7 @@ class CellBase(models.Model, metaclass=CellMeta):
for v in validity_info_list
if v.object_id == cell.pk and v.content_type.model_class() == cell.__class__
]
cells.sort(key=lambda x: x.order)
return cells

View File

@ -25,12 +25,14 @@ from django.template import Template, TemplateSyntaxError
from django.template.loader import TemplateDoesNotExist, get_template
from django.utils.translation import gettext_lazy as _
from combo import utils
from combo.data.forms import get_page_choices
from combo.data.models import Page, ParentContentCell, SiteSettings, compile_sub_slug
from .fields import ImageIncludingSvgField
@utils.cache_during_request
def get_groups_as_choices():
return [(x.id, x.name) for x in Group.objects.all().order_by('name')]

View File

@ -419,7 +419,12 @@ class PageView(ManagedPageMixin, DetailView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
cells = CellBase.get_cells(page=self.object, prefetch_validity_info=True)
cells = CellBase.get_cells(
page=self.object,
prefetch_validity_info=True,
prefetch_groups=True,
select_related={'__all__': ['page']},
)
existing_cell_types = {cell.get_cell_type_str() for cell in cells}
cell_type_groups = {}
for cell_type in CellBase.get_all_cell_types():

View File

@ -274,7 +274,7 @@ LINGO_NO_ONLINE_PAYMENT_REASONS = {}
JSON_CELL_TYPES = {}
# dashboard support
COMBO_DASHBOARD_ENABLED = True
COMBO_DASHBOARD_ENABLED = False
COMBO_DASHBOARD_NEW_TILE_POSITION = 'last'

View File

@ -702,7 +702,7 @@ def test_edit_page_num_queries(settings, app, admin_user):
app.get('/manage/pages/%s/' % page.pk) # load once to populate caches
with CaptureQueriesContext(connection) as ctx:
app.get('/manage/pages/%s/' % page.pk)
assert len(ctx.captured_queries) == 44
assert len(ctx.captured_queries) == 40
def test_delete_page(app, admin_user):
@ -2557,7 +2557,7 @@ def test_page_versionning(app, admin_user):
resp = resp.click('restore', index=6)
with CaptureQueriesContext(connection) as ctx:
resp = resp.form.submit().follow()
assert len(ctx.captured_queries) == 153
assert len(ctx.captured_queries) == 147
resp2 = resp.click('See online')
assert resp2.text.index('Foobar1') < resp2.text.index('Foobar2') < resp2.text.index('Foobar3')

View File

@ -686,23 +686,23 @@ def test_manager_card_cell(mock_send, app, admin_user):
assert resp.forms[0]['c%s-related_card_path' % cell.get_reference()].options == [
('__all__', False, 'All cards'),
('--', True, 'Card whose identifier is in the URL'),
('sluge-bis/cardd-bar/carde-foo', False, 'Linked card (From cell sluge-bis): "Card D" -> "Card E"'),
(
'sluge-again/cardd-bar/carde-foo',
False,
'Linked card (From cell sluge-again): "Card D" -> "Card E"',
),
('sluge-bis/cardd-bar/carde-foo', False, 'Linked card (From cell sluge-bis): "Card D" -> "Card E"'),
('', False, 'Template'),
]
assert resp.forms[1]['c%s-related_card_path' % cell2.get_reference()].options == [
('__all__', False, 'All cards'),
('--', True, 'Card whose identifier is in the URL'),
('sluge/cardd-bar/carde-foo', False, 'Linked card (From cell sluge): "Card D" -> "Card E"'),
(
'sluge-again/cardd-bar/carde-foo',
False,
'Linked card (From cell sluge-again): "Card D" -> "Card E"',
),
('sluge/cardd-bar/carde-foo', False, 'Linked card (From cell sluge): "Card D" -> "Card E"'),
('', False, 'Template'),
]