From 1e4e4d8e7c585a38d43269793370370663b5f51b Mon Sep 17 00:00:00 2001 From: msj Date: Fri, 20 Sep 2024 17:33:59 -0400 Subject: [PATCH 1/7] Optimize event detail page --- lametro/views.py | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/lametro/views.py b/lametro/views.py index f65d99ab..23c0e896 100644 --- a/lametro/views.py +++ b/lametro/views.py @@ -17,7 +17,18 @@ from django.contrib.auth.mixins import LoginRequiredMixin from django.shortcuts import render from django.db.models.functions import Lower, Now, Cast -from django.db.models import Max, Prefetch, Case, When, Value, IntegerField, Q, F +from django.db.models import ( + Max, + Prefetch, + Case, + When, + Value, + IntegerField, + Q, + F, + OuterRef, + Subquery, +) from django.urls import reverse from django.utils import timezone from django.views.generic import ( @@ -51,6 +62,12 @@ from councilmatic_core.models import Organization, Membership from opencivicdata.core.models import PersonLink +from opencivicdata.legislative.models import ( + Bill, + BillVersion, + BillAction, + EventRelatedEntity, +) from lametro.models import ( LAMetroBill, @@ -209,8 +226,33 @@ def get_context_data(self, **kwargs): except EventDocument.DoesNotExist: pass + most_recent_actions = ( + BillAction.objects.filter( + bill__eventrelatedentity__agenda_item__event=event + ) + .order_by("-date") + .values("id")[:1] + ) + related_entities = ( + EventRelatedEntity.objects.all() + .filter(agenda_item__event=event) + .select_related("bill") + .defer("bill__extras") + .prefetch_related( + "bill__versions", + "bill__versions__links", + Prefetch( + "bill__actions", + queryset=BillAction.objects.filter(id__in=most_recent_actions), + ), + ) + ) + agenda_with_board_reports = ( - event.agenda.filter(related_entities__bill__versions__isnull=False) + event.agenda.prefetch_related( + Prefetch("related_entities", queryset=related_entities), + ) + .filter(related_entities__bill__versions__isnull=False) .annotate(int_order=Cast("order", IntegerField())) .order_by("int_order") ) From 1f7677a99420e7f2cf515bf1ad6ccf889ac46415 Mon Sep 17 00:00:00 2001 From: msj Date: Fri, 20 Sep 2024 17:36:55 -0400 Subject: [PATCH 2/7] Lint --- lametro/views.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lametro/views.py b/lametro/views.py index 23c0e896..38f54058 100644 --- a/lametro/views.py +++ b/lametro/views.py @@ -26,8 +26,6 @@ IntegerField, Q, F, - OuterRef, - Subquery, ) from django.urls import reverse from django.utils import timezone @@ -63,8 +61,6 @@ from opencivicdata.core.models import PersonLink from opencivicdata.legislative.models import ( - Bill, - BillVersion, BillAction, EventRelatedEntity, ) From 241f24b9751c2f056cbb8a9551d783c753c4cc91 Mon Sep 17 00:00:00 2001 From: msj Date: Wed, 25 Sep 2024 16:03:19 -0400 Subject: [PATCH 3/7] Re-do queries --- lametro/templates/event/_related_bills.html | 4 +- lametro/templatetags/lametro_extras.py | 12 +++++- lametro/views.py | 47 +++++++++++---------- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/lametro/templates/event/_related_bills.html b/lametro/templates/event/_related_bills.html index f85da0b3..ec86dd34 100644 --- a/lametro/templates/event/_related_bills.html +++ b/lametro/templates/event/_related_bills.html @@ -14,11 +14,11 @@

Board Reports

{% with associated_bill=report.related_entities.all.0.bill %} {{ report.notes.0 | parse_agenda_item }} - {{associated_bill.identifier}} {{report.description | short_blurb}} {{ associated_bill.inferred_status | inferred_status_label | safe }} + {{associated_bill.identifier}} {{report.description | short_blurb}} {{ associated_bill.last_action_description | bill_status_from_last_action | inferred_status_label | safe }} View - Download + Download {% endwith %} {% endfor %} diff --git a/lametro/templatetags/lametro_extras.py b/lametro/templatetags/lametro_extras.py index 5566a5e1..060a1c80 100644 --- a/lametro/templatetags/lametro_extras.py +++ b/lametro/templatetags/lametro_extras.py @@ -7,7 +7,10 @@ from django import template from django.utils import timezone -from councilmatic.settings_jurisdiction import legislation_types +from councilmatic.settings_jurisdiction import ( + legislation_types, + BILL_STATUS_DESCRIPTIONS, +) from councilmatic.settings import PIC_BASE_URL from councilmatic_core.models import Person, Bill @@ -327,3 +330,10 @@ def get_events_with_manual_broadcasts(): broadcasts = EventBroadcast.objects.filter(is_manually_live=True) events = [b.event for b in broadcasts] return events + + +@register.filter +def bill_status_from_last_action(description): + if description and description.upper() in BILL_STATUS_DESCRIPTIONS.keys(): + return BILL_STATUS_DESCRIPTIONS[description.upper()]["search_term"] + return None diff --git a/lametro/views.py b/lametro/views.py index 38f54058..f65a672e 100644 --- a/lametro/views.py +++ b/lametro/views.py @@ -26,6 +26,8 @@ IntegerField, Q, F, + OuterRef, + Subquery, ) from django.urls import reverse from django.utils import timezone @@ -60,10 +62,7 @@ from councilmatic_core.models import Organization, Membership from opencivicdata.core.models import PersonLink -from opencivicdata.legislative.models import ( - BillAction, - EventRelatedEntity, -) +from opencivicdata.legislative.models import BillVersion, BillAction from lametro.models import ( LAMetroBill, @@ -222,35 +221,37 @@ def get_context_data(self, **kwargs): except EventDocument.DoesNotExist: pass - most_recent_actions = ( - BillAction.objects.filter( - bill__eventrelatedentity__agenda_item__event=event - ) - .order_by("-date") - .values("id")[:1] + latest_action = BillAction.objects.filter(bill=OuterRef("pk")).order_by( + "-order" ) - related_entities = ( - EventRelatedEntity.objects.all() - .filter(agenda_item__event=event) - .select_related("bill") - .defer("bill__extras") + + related_bills = ( + LAMetroBill.objects.filter(eventrelatedentity__agenda_item__event=event) + .defer("extras") .prefetch_related( - "bill__versions", - "bill__versions__links", Prefetch( - "bill__actions", - queryset=BillAction.objects.filter(id__in=most_recent_actions), + "versions", + queryset=BillVersion.objects.filter( + note="Board Report" + ).prefetch_related("links"), + to_attr="br", ), + "packet", + ) + .annotate( + last_action_description=Subquery( + latest_action.values("description")[:1] + ) ) ) agenda_with_board_reports = ( - event.agenda.prefetch_related( - Prefetch("related_entities", queryset=related_entities), - ) - .filter(related_entities__bill__versions__isnull=False) + event.agenda.filter(related_entities__bill__versions__isnull=False) .annotate(int_order=Cast("order", IntegerField())) .order_by("int_order") + .prefetch_related( + Prefetch("related_entities__bill", queryset=related_bills) + ) ) # Find agenda link. From 8cf62b4167039078da0ec9a3c236fc27c0c36332 Mon Sep 17 00:00:00 2001 From: msj Date: Thu, 26 Sep 2024 14:53:16 -0400 Subject: [PATCH 4/7] Move last action annotation to bill manager --- lametro/models.py | 39 ++++++++++++++++++++++++++++++++++++++- lametro/views.py | 12 ++---------- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/lametro/models.py b/lametro/models.py index e187f361..244b6a9a 100644 --- a/lametro/models.py +++ b/lametro/models.py @@ -15,7 +15,7 @@ from django.utils.functional import cached_property from django.core.cache import cache -from django.db.models import Prefetch, Case, When, Value, Q, F +from django.db.models import Prefetch, Case, When, Value, Q, F, Subquery, OuterRef from django.db.models.functions import Now, Cast from django.templatetags.static import static from opencivicdata.legislative.models import ( @@ -24,6 +24,7 @@ EventRelatedEntity, RelatedBill, BillVersion, + BillAction, ) from proxy_overrides.related import ProxyForeignKey @@ -148,6 +149,17 @@ def get_queryset(self): return qs + def with_latest_actions(self): + latest_action = BillAction.objects.filter(bill=OuterRef("pk")).order_by( + "-order" + ) + + qs = self.annotate( + last_action_description=Subquery(latest_action.values("description")[:1]) + ) + + return qs + class LAMetroBill(Bill, SourcesMixin): objects = LAMetroBillManager() @@ -530,6 +542,31 @@ def with_media(self): Prefetch("media", queryset=mediaqueryset) ).prefetch_related("media__links") + def with_related_bills(self): + latest_action = BillAction.objects.filter(bill=OuterRef("pk")).order_by( + "-order" + ) + + related_bills = ( + LAMetroBill.objects.filter(eventrelatedentity__agenda_item__event=event) + .defer("extras") + .prefetch_related( + Prefetch( + "versions", + queryset=BillVersion.objects.filter( + note="Board Report" + ).prefetch_related("links"), + to_attr="br", + ), + "packet", + ) + .annotate( + last_action_description=Subquery( + latest_action.values("description")[:1] + ) + ) + ) + class LiveMediaMixin(object): BASE_MEDIA_URL = "http://metro.granicus.com/mediaplayer.php?" diff --git a/lametro/views.py b/lametro/views.py index f65a672e..54c73304 100644 --- a/lametro/views.py +++ b/lametro/views.py @@ -221,13 +221,10 @@ def get_context_data(self, **kwargs): except EventDocument.DoesNotExist: pass - latest_action = BillAction.objects.filter(bill=OuterRef("pk")).order_by( - "-order" - ) - related_bills = ( - LAMetroBill.objects.filter(eventrelatedentity__agenda_item__event=event) + LAMetroBill.objects.with_latest_actions() .defer("extras") + .filter(eventrelatedentity__agenda_item__event=event) .prefetch_related( Prefetch( "versions", @@ -238,11 +235,6 @@ def get_context_data(self, **kwargs): ), "packet", ) - .annotate( - last_action_description=Subquery( - latest_action.values("description")[:1] - ) - ) ) agenda_with_board_reports = ( From ca32625ad24d2b185ebfe70ca2185f7092be29b0 Mon Sep 17 00:00:00 2001 From: msj Date: Thu, 26 Sep 2024 14:56:48 -0400 Subject: [PATCH 5/7] Lint --- lametro/views.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lametro/views.py b/lametro/views.py index 54c73304..eed06767 100644 --- a/lametro/views.py +++ b/lametro/views.py @@ -26,8 +26,6 @@ IntegerField, Q, F, - OuterRef, - Subquery, ) from django.urls import reverse from django.utils import timezone @@ -62,7 +60,7 @@ from councilmatic_core.models import Organization, Membership from opencivicdata.core.models import PersonLink -from opencivicdata.legislative.models import BillVersion, BillAction +from opencivicdata.legislative.models import BillVersion from lametro.models import ( LAMetroBill, From ffc5776eb54ab81d01d0125ebf04b831f2364587 Mon Sep 17 00:00:00 2001 From: msj Date: Thu, 26 Sep 2024 15:03:55 -0400 Subject: [PATCH 6/7] Remove unnecessary function --- lametro/models.py | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/lametro/models.py b/lametro/models.py index 244b6a9a..7533db2b 100644 --- a/lametro/models.py +++ b/lametro/models.py @@ -542,31 +542,6 @@ def with_media(self): Prefetch("media", queryset=mediaqueryset) ).prefetch_related("media__links") - def with_related_bills(self): - latest_action = BillAction.objects.filter(bill=OuterRef("pk")).order_by( - "-order" - ) - - related_bills = ( - LAMetroBill.objects.filter(eventrelatedentity__agenda_item__event=event) - .defer("extras") - .prefetch_related( - Prefetch( - "versions", - queryset=BillVersion.objects.filter( - note="Board Report" - ).prefetch_related("links"), - to_attr="br", - ), - "packet", - ) - .annotate( - last_action_description=Subquery( - latest_action.values("description")[:1] - ) - ) - ) - class LiveMediaMixin(object): BASE_MEDIA_URL = "http://metro.granicus.com/mediaplayer.php?" From f232aa341049f272b1a64ae84d15d00811d953cd Mon Sep 17 00:00:00 2001 From: msj Date: Tue, 1 Oct 2024 09:54:33 -0400 Subject: [PATCH 7/7] Fix board report url --- lametro/templates/event/_related_bills.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lametro/templates/event/_related_bills.html b/lametro/templates/event/_related_bills.html index ec86dd34..6a2f4cbe 100644 --- a/lametro/templates/event/_related_bills.html +++ b/lametro/templates/event/_related_bills.html @@ -18,7 +18,7 @@

Board Reports

View - Download + Download {% endwith %} {% endfor %}