Projet

Général

Profil

0002-manager-reduce-querysets-on-agenda-settings-page-486.patch

Lauréline Guérin, 19 novembre 2020 17:22

Télécharger (4,57 ko)

Voir les différences:

Subject: [PATCH 2/2] manager: reduce querysets on agenda settings page
 (#48624)

 chrono/agendas/models.py | 13 +++++--------
 chrono/manager/views.py  | 18 +++++++++++++++++-
 tests/test_manager.py    |  2 +-
 3 files changed, 23 insertions(+), 10 deletions(-)
chrono/agendas/models.py
1210 1210
        return new_desk
1211 1211

  
1212 1212
    def get_exceptions_within_two_weeks(self):
1213
        # FIXME : optimize DB queries, on the settings view this is called once per desk
1213
        # prefetched_exceptions contains desks exceptions + unavailability_calendars exceptions
1214 1214
        # default ordering: start_datetime
1215 1215
        in_two_weeks = make_aware(datetime.datetime.today() + datetime.timedelta(days=14))
1216 1216
        exceptions = []
1217
        queryset = TimePeriodException.objects.filter(Q(desk=self) | Q(unavailability_calendar__desks=self))
1218
        for exception in queryset.all():
1217
        for exception in self.prefetched_exceptions:
1219 1218
            if exception.end_datetime < now():
1220 1219
                # exception ends in the past, skip it
1221 1220
                continue
......
1228 1227
        if exceptions:
1229 1228
            return exceptions
1230 1229
        # if none found within the 2 coming weeks, return the next one
1231
        for exception in queryset.all():
1230
        for exception in self.prefetched_exceptions:
1232 1231
            if exception.start_datetime < now():
1233 1232
                # exception starts in the past, skip it
1234 1233
                continue
......
1238 1237

  
1239 1238
    def are_all_exceptions_displayed(self):
1240 1239
        in_two_weeks = self.get_exceptions_within_two_weeks()
1241
        return TimePeriodException.objects.filter(
1242
            Q(desk=self) | Q(unavailability_calendar__desks=self)
1243
        ).count() == len(in_two_weeks)
1240
        return len(self.prefetched_exceptions) == len(in_two_weeks)
1244 1241

  
1245 1242
    def import_timeperiod_exceptions_from_remote_ics(self, ics_url, source=None):
1246 1243
        try:
......
1621 1618

  
1622 1619
    @property
1623 1620
    def read_only(self):
1624
        return self.source and self.source.settings_slug or self.unavailability_calendar
1621
        return self.source and self.source.settings_slug or self.unavailability_calendar_id
1625 1622

  
1626 1623
    class Meta:
1627 1624
        ordering = ['start_datetime']
chrono/manager/views.py
1325 1325
class AgendaSettings(ManagedAgendaMixin, DetailView):
1326 1326
    model = Agenda
1327 1327

  
1328
    def set_agenda(self, **kwargs):
1329
        self.agenda = get_object_or_404(
1330
            Agenda.objects.select_related('edit_role', 'view_role'), pk=kwargs.get('pk')
1331
        )
1332

  
1328 1333
    def get_object(self, *args, **kwargs):
1329 1334
        if self.agenda.kind == 'meetings':
1330 1335
            self.agenda.prefetched_desks = self.agenda.desk_set.all().prefetch_related(
1331
                'timeperiod_set', 'timeperiodexception_set',
1336
                'timeperiod_set', 'unavailability_calendars',
1332 1337
            )
1338
            all_desks_exceptions = TimePeriodException.objects.filter(
1339
                Q(desk__in=self.agenda.prefetched_desks)
1340
                | Q(unavailability_calendar__desks__in=self.agenda.prefetched_desks)
1341
            ).select_related('source')
1342
            for desk in self.agenda.prefetched_desks:
1343
                uc_ids = [uc.pk for uc in desk.unavailability_calendars.all()]
1344
                desk.prefetched_exceptions = [
1345
                    e
1346
                    for e in all_desks_exceptions
1347
                    if e.desk_id == desk.pk or e.unavailability_calendar_id in uc_ids
1348
                ]
1333 1349
        return self.agenda
1334 1350

  
1335 1351
    def get_context_data(self, **kwargs):
tests/test_manager.py
1042 1042
    app = login(app)
1043 1043
    with CaptureQueriesContext(connection) as ctx:
1044 1044
        app.get('/manage/agendas/%s/settings' % agenda.pk)
1045
        assert len(ctx.captured_queries) == 63
1045
        assert len(ctx.captured_queries) == 12
1046 1046

  
1047 1047

  
1048 1048
def test_agenda_resources(app, admin_user):
1049
-