Projet

Général

Profil

0002-agendas-reduce-querysets-on-settings-view-43516.patch

Lauréline Guérin, 02 juin 2020 10:08

Télécharger (5,38 ko)

Voir les différences:

Subject: [PATCH 2/2] agendas: reduce querysets on settings view (#43516)

 chrono/agendas/models.py                      | 31 +++++++++++++------
 .../manager_meetings_agenda_settings.html     | 12 ++++---
 chrono/manager/views.py                       |  4 +++
 tests/test_manager.py                         |  2 +-
 4 files changed, 33 insertions(+), 16 deletions(-)
chrono/agendas/models.py
929 929
        return new_desk
930 930

  
931 931
    def get_exceptions_within_two_weeks(self):
932
        # timeperiodexception_set.all() is prefetched, do not filter the querysets
932 933
        in_two_weeks = make_aware(datetime.datetime.today() + datetime.timedelta(days=14))
933
        exceptions = self.timeperiodexception_set.filter(end_datetime__gte=now()).filter(
934
            Q(end_datetime__lte=in_two_weeks) | Q(start_datetime__lt=now())
935
        )
936
        if exceptions.exists():
934
        exceptions = []
935
        for exception in self.timeperiodexception_set.all():
936
            if exception.end_datetime < now():
937
                # exception ends in the past, skip it
938
                continue
939
            if exception.end_datetime <= in_two_weeks:
940
                # ends in less than 2 weeks
941
                exceptions.append(exception)
942
            elif exception.start_datetime < now():
943
                # has already started
944
                exceptions.append(exception)
945
        if exceptions:
937 946
            return exceptions
938 947
        # if none found within the 2 coming weeks, return the next one
939
        next_exception = (
940
            self.timeperiodexception_set.filter(start_datetime__gte=now()).order_by('start_datetime').first()
941
        )
942
        if next_exception:
943
            return [next_exception]
948
        for exception in self.timeperiodexception_set.all():
949
            if exception.start_datetime < now():
950
                # exception starts in the past, skip it
951
                continue
952
            # returns the first exception found
953
            return [exception]
944 954
        return []
945 955

  
946 956
    def are_all_exceptions_displayed(self):
957
        # timeperiod_set.all() is prefetched, do not filter the queryset
947 958
        in_two_weeks = self.get_exceptions_within_two_weeks()
948
        return self.timeperiodexception_set.count() == len(in_two_weeks)
959
        return len(self.timeperiodexception_set.all()) == len(in_two_weeks)
949 960

  
950 961
    def import_timeperiod_exceptions_from_remote_ics(self, ics_url, source=None):
951 962
        try:
chrono/manager/templates/chrono/manager_meetings_agenda_settings.html
22 22
<div class="section">
23 23
<h3>{% trans 'Meeting Types' %}</h3>
24 24
<div>
25
{% if object.meetingtype_set.count %}
25
{% with object.meetingtype_set.all as meetingtypes %}
26
{% if meetingtypes %}
26 27
  <ul class="objects-list single-links">
27
    {% for meeting_type in object.meetingtype_set.all %}
28
    {% for meeting_type in meetingtypes %}
28 29
    <li><a rel="popup" href="{% url 'chrono-manager-meeting-type-edit' pk=meeting_type.id %}">
29 30
        {{meeting_type.label}}
30 31
        <span class="duration">({{meeting_type.duration}} {% trans "minutes" %})</span>
......
42 43
  {% endblocktrans %}
43 44
</div>
44 45
{% endif %}
46
{% endwith %}
45 47
</div>
46 48
</div>
47 49

  
48 50
<div class="section">
49 51
<h3>{% trans 'Time Periods' %}</h3>
50 52
<div>
51
    {% if object.desk_set.count %}
53
    {% if object.prefetched_desks %}
52 54
    <div class="timeperiods">
53
        {% for desk in object.desk_set.all %}
55
        {% for desk in object.prefetched_desks %}
54 56
        <div class="timeperiod">
55 57
            {% url 'chrono-manager-agenda-add-time-period' agenda_pk=object.pk pk=desk.pk as add_time_period_url %}
56 58
            <ul class="objects-list single-links">
......
93 95
    the top right of the page to add a first one.
94 96
    {% endblocktrans %}
95 97
    </div>
96
{% endif %}
98
    {% endif %}
97 99
</div>
98 100
</div>
99 101

  
chrono/manager/views.py
723 723
    model = Agenda
724 724

  
725 725
    def get_object(self, *args, **kwargs):
726
        if self.agenda.kind == 'meetings':
727
            self.agenda.prefetched_desks = self.agenda.desk_set.all().prefetch_related(
728
                'timeperiod_set', 'timeperiodexception_set',
729
            )
726 730
        return self.agenda
727 731

  
728 732
    def get_context_data(self, **kwargs):
tests/test_manager.py
316 316
    app = login(app)
317 317
    with CaptureQueriesContext(connection) as ctx:
318 318
        app.get('/manage/agendas/%s/settings' % agenda.pk)
319
        assert len(ctx.captured_queries) == 77
319
        assert len(ctx.captured_queries) == 7
320 320

  
321 321

  
322 322
def test_delete_agenda(app, admin_user):
323
-