Projet

Général

Profil

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

Valentin Deniaud, 27 avril 2021 18:01

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
660 660

  
661 661
        if prefetched_queryset:
662 662
            recurring_events = self.prefetched_recurring_events
663
            exceptions = self.prefetched_exceptions
663 664
        else:
664 665
            recurring_events = self.event_set.filter(recurrence_rule__isnull=False)
666
            exceptions = self.get_recurrence_exceptions(min_start, max_start)
665 667

  
666
        exceptions = self.get_recurrence_exceptions(min_start, max_start)
667 668
        for event in recurring_events:
668 669
            events.extend(
669 670
                event.get_recurrences(
chrono/api/views.py
565 565
                start_datetime__gte=localtime(now()),
566 566
            ).order_by()
567 567
            recurring_event_queryset = Event.objects.filter(recurrence_rule__isnull=False)
568
            exceptions_desk = Desk.objects.filter(slug='_exceptions_holder').prefetch_related(
569
                'unavailability_calendars'
570
            )
568 571
            agendas_queryset = agendas_queryset.filter(kind='events').prefetch_related(
569 572
                Prefetch(
570 573
                    'event_set',
......
576 579
                    queryset=recurring_event_queryset,
577 580
                    to_attr='prefetched_recurring_events',
578 581
                ),
582
                Prefetch(
583
                    'desk_set',
584
                    queryset=exceptions_desk,
585
                    to_attr='prefetched_desks',
586
                ),
587
            )
588
            agendas_exceptions = TimePeriodException.objects.filter(
589
                Q(desk__slug='_exceptions_holder', desk__agenda__in=agendas_queryset)
590
                | Q(
591
                    unavailability_calendar__desks__slug='_exceptions_holder',
592
                    unavailability_calendar__desks__agenda__in=agendas_queryset,
593
                ),
594
                start_datetime__gte=localtime(now()),
579 595
            )
580 596

  
581 597
        agendas = []
582 598
        for agenda in agendas_queryset:
583
            if with_open_events and not any(
584
                not e.full for e in agenda.get_open_events(prefetched_queryset=True)
585
            ):
586
                # exclude agendas without open events
587
                continue
599
            if with_open_events:
600
                desk = agenda.prefetched_desks[0]
601
                uc_ids = [uc.pk for uc in desk.unavailability_calendars.all()]
602
                agenda.prefetched_exceptions = [
603
                    e
604
                    for e in agendas_exceptions
605
                    if e.desk_id == desk.pk or e.unavailability_calendar_id in uc_ids
606
                ]
607
                if not any(not e.full for e in agenda.get_open_events(prefetched_queryset=True)):
608
                    # exclude agendas without open events
609
                    continue
588 610
            agendas.append(get_agenda_detail(request, agenda))
589 611

  
590 612
        return Response({'data': agendas})
tests/test_api.py
317 317

  
318 318
    with CaptureQueriesContext(connection) as ctx:
319 319
        resp = app.get('/api/agenda/', params={'with_open_events': '1'})
320
        assert len(ctx.captured_queries) == 15
320
        assert len(ctx.captured_queries) == 7
321 321

  
322 322

  
323 323
def test_agendas_meetingtypes_api(app, some_data, meetings_agenda):
324
-