Projet

Général

Profil

0003-api-prefetch-exceptions-for-recurring-events-50561.patch

Valentin Deniaud, 22 février 2021 15:25

Télécharger (3,98 ko)

Voir les différences:

Subject: [PATCH 3/4] api: prefetch exceptions for recurring events (#50561)

 chrono/agendas/models.py |  3 ++-
 chrono/api/views.py      | 32 +++++++++++++++++++++++++++-----
 tests/test_api.py        |  2 +-
 3 files changed, 30 insertions(+), 7 deletions(-)
chrono/agendas/models.py
596 596

  
597 597
        if prefetched_queryset:
598 598
            recurring_events = self.prefetched_recurring_events
599
            exceptions = self.prefetched_exceptions
599 600
        else:
600 601
            recurring_events = self.event_set.filter(recurrence_rule__isnull=False)
602
            exceptions = self.get_recurrence_exceptions(min_start, max_start)
601 603

  
602
        exceptions = self.get_recurrence_exceptions(min_start, max_start)
603 604
        for event in recurring_events:
604 605
            events.extend(
605 606
                event.get_recurrences(
chrono/api/views.py
492 492
                start_datetime__gte=localtime(now()),
493 493
            ).order_by()
494 494
            recurring_event_queryset = Event.objects.filter(recurrence_rule__isnull=False)
495
            exceptions_desk = Desk.objects.filter(slug='_exceptions_holder').prefetch_related(
496
                'unavailability_calendars'
497
            )
495 498
            agendas_queryset = agendas_queryset.filter(kind='events').prefetch_related(
496 499
                Prefetch(
497 500
                    'event_set',
......
503 506
                    queryset=recurring_event_queryset,
504 507
                    to_attr='prefetched_recurring_events',
505 508
                ),
509
                Prefetch(
510
                    'desk_set',
511
                    queryset=exceptions_desk,
512
                    to_attr='prefetched_desks',
513
                ),
514
            )
515
            agendas_exceptions = TimePeriodException.objects.filter(
516
                Q(desk__slug='_exceptions_holder', desk__agenda__in=agendas_queryset)
517
                | Q(
518
                    unavailability_calendar__desks__slug='_exceptions_holder',
519
                    unavailability_calendar__desks__agenda__in=agendas_queryset,
520
                ),
521
                start_datetime__gte=localtime(now()),
506 522
            )
507 523

  
508 524
        agendas = []
509 525
        for agenda in agendas_queryset:
510
            if with_open_events and not any(
511
                not e.full for e in agenda.get_open_events(prefetched_queryset=True)
512
            ):
513
                # exclude agendas without open events
514
                continue
526
            if with_open_events:
527
                desk = agenda.prefetched_desks[0]
528
                uc_ids = [uc.pk for uc in desk.unavailability_calendars.all()]
529
                agenda.prefetched_exceptions = [
530
                    e
531
                    for e in agendas_exceptions
532
                    if e.desk_id == desk.pk or e.unavailability_calendar_id in uc_ids
533
                ]
534
                if not any(not e.full for e in agenda.get_open_events(prefetched_queryset=True)):
535
                    # exclude agendas without open events
536
                    continue
515 537
            agendas.append(get_agenda_detail(request, agenda))
516 538

  
517 539
        return Response({'data': agendas})
tests/test_api.py
309 309

  
310 310
    with CaptureQueriesContext(connection) as ctx:
311 311
        resp = app.get('/api/agenda/', params={'with_open_events': '1'})
312
        assert len(ctx.captured_queries) == 6
312
        assert len(ctx.captured_queries) == 7
313 313

  
314 314

  
315 315
def test_agendas_meetingtypes_api(app, some_data, meetings_agenda):
316
-