From 698e75cca4d72691222df2a42057332db9a49bb6 Mon Sep 17 00:00:00 2001 From: Derek Eder Date: Fri, 1 Sep 2023 16:32:06 -0500 Subject: [PATCH 1/8] adds vimeo embed if available, event agenda is a table with links and sponsors --- chicago/models.py | 24 +++++++++++++++++ chicago/templates/event.html | 50 ++++++++++++++++++++++++++---------- 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/chicago/models.py b/chicago/models.py index ecec557..d641858 100644 --- a/chicago/models.py +++ b/chicago/models.py @@ -172,6 +172,30 @@ def most_recent_past_city_council_meeting(cls): else: return None + @property + def clean_agenda_items(self): + agenda_items = ( + self.agenda.order_by("order").all().prefetch_related("related_entities") + ) + agenda_deduped = [] + descriptions_seen = [] + for a in agenda_items: + if a.description not in descriptions_seen: + descriptions_seen.append(a.description) + agenda_deduped.append(a) + + return agenda_deduped + + @property + def video_vimeo_id(self): + try: + link = self.media.first().links.first().url + vimeo_id = re.match(".*?([0-9]+)$", link).group(1) + print(link, vimeo_id) + return vimeo_id + except AttributeError: + return None + class ChicagoPerson(Person): class Meta: diff --git a/chicago/templates/event.html b/chicago/templates/event.html index dcef56a..56b9181 100644 --- a/chicago/templates/event.html +++ b/chicago/templates/event.html @@ -23,28 +23,50 @@

{%if event.status == 'cancelled'%}CANCELLED: {% endif %}{{event.name}}

{{event.location}}

+ {% if event.video_vimeo_id %} + +

View on Vimeo

+ {% endif %}
{% if event.clean_agenda_items %}

Agenda

-

-

    + + + + + + + + + + {% for agenda_item in event.clean_agenda_items %} - {% if agenda_item.description|lower != 'page break' %} -
  1. - {% if agenda_item.related_bills.all %} - - {{agenda_item.related_bills.first.bill.friendly_name}} - -
    +
  2. + {% if agenda_item.description|lower != 'page break' %} + + + {% if agenda_item.related_entities.first.bill.councilmatic_bill %} + + + {% else %} + + {% endif %} - {{agenda_item.description}} - - {% endif %} + {% endif %} + {% endfor %} - -

    + +
    OrderDescriptionIDSponsor(s)
    {{ forloop.counter }}{{agenda_item.description}} + + {{ agenda_item.related_entities.first.bill.councilmatic_bill.friendly_name }} + + + {% for s in agenda_item.related_entities.first.bill.councilmatic_bill.sponsorships.all %} + {{ s.person.link_html | safe }}{% if not forloop.last %},{% endif %} + {% endfor %} +
    {% endif %} {% if event.documents.all %} From 5b3b3645cf3bbddb36c83cbfc2789aa5dcddd1d3 Mon Sep 17 00:00:00 2001 From: Derek Eder Date: Fri, 8 Sep 2023 15:59:27 -0500 Subject: [PATCH 2/8] working to optimize query, saving prefetch to to_attr, but getting an error --- chicago/models.py | 27 ++++++++++++++++++--------- chicago/templates/event.html | 2 +- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/chicago/models.py b/chicago/models.py index d641858..4cf5c6c 100644 --- a/chicago/models.py +++ b/chicago/models.py @@ -11,6 +11,7 @@ from django.conf import settings from django.db import models +from django.db.models import Prefetch from .helpers import topic_classifier app_timezone = pytz.timezone(settings.TIME_ZONE) @@ -174,17 +175,25 @@ def most_recent_past_city_council_meeting(cls): @property def clean_agenda_items(self): - agenda_items = ( - self.agenda.order_by("order").all().prefetch_related("related_entities") - ) - agenda_deduped = [] - descriptions_seen = [] + + agenda_items = self.agenda.order_by("order").prefetch_related( + Prefetch( + "related_entities__bill__councilmatic_bill", + to_attr="councilmatic_bills", + ) + )[:10] + print(agenda_items.query) + # agenda_deduped = [] + # descriptions_seen = [] + # for a in agenda_items: + # if a.description not in descriptions_seen: + # descriptions_seen.append(a.description) + # agenda_deduped.append(a) + for a in agenda_items: - if a.description not in descriptions_seen: - descriptions_seen.append(a.description) - agenda_deduped.append(a) + print(a.councilmatic_bills) - return agenda_deduped + return agenda_items @property def video_vimeo_id(self): diff --git a/chicago/templates/event.html b/chicago/templates/event.html index 56b9181..47de9bc 100644 --- a/chicago/templates/event.html +++ b/chicago/templates/event.html @@ -47,7 +47,7 @@

    Agenda

    {% if agenda_item.description|lower != 'page break' %} {{ forloop.counter }} {{agenda_item.description}} - {% if agenda_item.related_entities.first.bill.councilmatic_bill %} + {% if agenda_item.related_entities.first.bill %} {{ agenda_item.related_entities.first.bill.councilmatic_bill.friendly_name }} From de2079d9f0ac2de1df29289353197a2ef36298e1 Mon Sep 17 00:00:00 2001 From: Forest Gregg Date: Fri, 8 Sep 2023 20:29:11 -0400 Subject: [PATCH 3/8] optimizing queries --- chicago/models.py | 43 ++++++++++++++++++------------------ chicago/templates/event.html | 10 ++++----- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/chicago/models.py b/chicago/models.py index 4cf5c6c..765204f 100644 --- a/chicago/models.py +++ b/chicago/models.py @@ -1,17 +1,19 @@ import re -from operator import attrgetter -import pytz -from django.utils import timezone -from django.utils.functional import cached_property from datetime import datetime -from dateutil.relativedelta import relativedelta +from operator import attrgetter +import pytz from councilmatic_core.models import Bill, Event, Organization, Person -from opencivicdata.legislative.models import LegislativeSession - +from dateutil.relativedelta import relativedelta from django.conf import settings from django.db import models from django.db.models import Prefetch +from django.utils import timezone +from django.utils.functional import cached_property +from opencivicdata.legislative.models import (BillSponsorship, + EventRelatedEntity, + LegislativeSession) + from .helpers import topic_classifier app_timezone = pytz.timezone(settings.TIME_ZONE) @@ -176,22 +178,19 @@ def most_recent_past_city_council_meeting(cls): @property def clean_agenda_items(self): - agenda_items = self.agenda.order_by("order").prefetch_related( - Prefetch( - "related_entities__bill__councilmatic_bill", - to_attr="councilmatic_bills", + sponsors = BillSponsorship.objects.filter(entity_type="person").select_related( + "person__councilmatic_person" + ) + related_bill = ( + EventRelatedEntity.objects.filter(entity_type="bill") + .select_related("bill__councilmatic_bill") + .prefetch_related( + Prefetch("bill__sponsorships", queryset=sponsors, to_attr="sponsors") ) - )[:10] - print(agenda_items.query) - # agenda_deduped = [] - # descriptions_seen = [] - # for a in agenda_items: - # if a.description not in descriptions_seen: - # descriptions_seen.append(a.description) - # agenda_deduped.append(a) - - for a in agenda_items: - print(a.councilmatic_bills) + ) + agenda_items = self.agenda.order_by("order").prefetch_related( + Prefetch("related_entities", queryset=related_bill, to_attr="bills") + ) return agenda_items diff --git a/chicago/templates/event.html b/chicago/templates/event.html index 47de9bc..6bf058d 100644 --- a/chicago/templates/event.html +++ b/chicago/templates/event.html @@ -47,15 +47,15 @@

    Agenda

    {% if agenda_item.description|lower != 'page break' %} {{ forloop.counter }} {{agenda_item.description}} - {% if agenda_item.related_entities.first.bill %} + {% if agenda_item.bills %} -
    - {{ agenda_item.related_entities.first.bill.councilmatic_bill.friendly_name }} + + {{ agenda_item.bills.0.bill.councilmatic_bill.friendly_name }} - {% for s in agenda_item.related_entities.first.bill.councilmatic_bill.sponsorships.all %} - {{ s.person.link_html | safe }}{% if not forloop.last %},{% endif %} + {% for s in agenda_item.bills.0.bill.sponsors %} + {{ s.person.councilmatic_person.link_html | safe }}{% if not forloop.last %},{% endif %} {% endfor %} {% else %} From 6944f59400b3be56596b3ae1d4dc16bbd36a09e9 Mon Sep 17 00:00:00 2001 From: Forest Gregg Date: Sat, 9 Sep 2023 00:25:00 -0400 Subject: [PATCH 4/8] speed up bill detail pages too --- chicago/templates/partials/seo.html | 2 +- chicago/views.py | 117 +++++++++++++--------------- 2 files changed, 56 insertions(+), 63 deletions(-) diff --git a/chicago/templates/partials/seo.html b/chicago/templates/partials/seo.html index 64eb4bd..0117e9b 100644 --- a/chicago/templates/partials/seo.html +++ b/chicago/templates/partials/seo.html @@ -8,7 +8,7 @@ - {% if seo.nofollow %} + {% if seo.noindex %} {% endif %} diff --git a/chicago/views.py b/chicago/views.py index f22daa4..62b3962 100644 --- a/chicago/views.py +++ b/chicago/views.py @@ -1,34 +1,34 @@ import itertools -from operator import attrgetter -from django.db.models import Min -from dateutil import parser from datetime import datetime -import pytz -from dateutil.relativedelta import relativedelta +from operator import attrgetter from urllib.parse import urlencode -from django.conf import settings -from django.http import Http404, HttpResponsePermanentRedirect -from django.urls import reverse -from django.db.models import Max -from django.utils import timezone -from django.views.generic import ListView -from opencivicdata.legislative.models import LegislativeSession -from chicago.models import ChicagoBill, ChicagoEvent, ChicagoOrganization, ChicagoPerson +import pytz +from councilmatic_core.models import Organization, Post from councilmatic_core.views import ( - IndexView, AboutView, BillDetailView, - CouncilMembersView, - PersonDetailView, - EventsView, - EventDetailView, - CommitteesView, CommitteeDetailView, + CommitteesView, CouncilmaticSearchForm, + CouncilMembersView, + EventDetailView, + EventsView, + IndexView, + PersonDetailView, ) -from councilmatic_core.models import Post, Organization +from dateutil import parser +from dateutil.relativedelta import relativedelta +from django.conf import settings +from django.db.models import Max, Min, Prefetch +from django.http import Http404, HttpResponsePermanentRedirect +from django.urls import reverse +from django.utils import timezone +from django.views.generic import ListView, DetailView from haystack.generic_views import FacetedSearchView +from opencivicdata.legislative.models import LegislativeSession, PersonVote + +from chicago.models import ChicagoBill, ChicagoEvent, ChicagoOrganization, ChicagoPerson class ChicagoIndexView(IndexView): @@ -203,20 +203,19 @@ def _get_query_parameters(self): return "" -class ChicagoBillDetailView(BillDetailView): - template_name = "legislation.html" - +class ChicagoBillDetailView(DetailView): model = ChicagoBill + template_name = "legislation.html" + context_object_name = "legislation" - def dispatch(self, request, *args, **kwargs): - slug = self.kwargs["slug"] + def get(self, request, *args, **kwargs): try: - bill = self.model.objects.get(slug=slug) - return super().dispatch(request, *args, **kwargs) - except ChicagoBill.DoesNotExist: + return super().get(request, *args, **kwargs) + except Http404: # the new Clerk LMS minted new IDs for existing bills in Legistar # this handles redirects from old bill IDs to new ones + slug = self.kwargs["slug"] try: bill = self.model.objects.get( other_identifiers__identifier__iexact=slug @@ -225,45 +224,39 @@ def dispatch(self, request, *args, **kwargs): reverse("bill_detail", args=[bill.slug]) ) - except ChicagoBill.DoesNotExist: + except self.model.DoesNotExist: raise Http404 - def get_object(self, queryset=None): - """ - Returns a bill based on slug. If no bill found, - looks for bills based on legistar id (so that - urls from old Chicago councilmatic don't break) - """ - - if queryset is None: - queryset = self.get_queryset() - - slug = self.kwargs.get(self.slug_url_kwarg) - if slug is None: - raise AttributeError( - "Generic detail view %s must be called with " - "either an object pk or a slug." % self.__class__.__name__ + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + bill = self.object + + context["actions"] = ( + bill.actions.order_by("-order") + .select_related("organization__councilmatic_organization") + .select_related("vote") + .prefetch_related( + Prefetch( + "vote__votes", + queryset=PersonVote.objects.select_related( + "voter__councilmatic_person" + ), + ) ) + ) - # Try looking up by slug - if slug is not None: - slug_field = self.get_slug_field() - queryset = queryset.filter(**{slug_field: slug}) - - try: - # Get the single item from the filtered queryset - obj = queryset.get() - except queryset.model.DoesNotExist: - raise Http404("No bill found matching the query") - - return obj + seo = {} + seo.update(settings.SITE_META) + seo["site_desc"] = bill.listing_description + seo["title"] = "%s - %s" % (bill.friendly_name, settings.SITE_META["site_name"]) + context["seo"] = seo - def get_context_data(self, **kwargs): - context = super(ChicagoBillDetailView, self).get_context_data(**kwargs) - (bill_classification,) = context["object"].classification - bill_identifier = context["object"].identifier + (bill_classification,) = bill.classification + bill_identifier = bill.identifier if bill_classification in {"claim"} or bill_identifier == "Or 2013-382": - context["seo"]["nofollow"] = True + context["seo"]["noindex"] = True + return context @@ -512,7 +505,7 @@ def get_context_data(self, **kwargs): for event_org in event_orgs: org_members = event_org.organization.memberships.filter( start_date__lte=event.start_time, end_date__gte=event.start_time - ) + ).select_related("person__councilmatic_person") expected_attendees.update([m.person for m in org_members]) attendees = set() From 0fca007ecabec6e3a76535e8b9ad81f1abb4923d Mon Sep 17 00:00:00 2001 From: Forest Gregg Date: Sat, 9 Sep 2023 23:04:47 -0400 Subject: [PATCH 5/8] leveraging get_queryset and misc tidies --- chicago/models.py | 23 +------- chicago/templates/event.html | 4 +- chicago/templates/legislation.html | 36 ++++++------- chicago/views.py | 86 +++++++++++++++++++++++++----- 4 files changed, 95 insertions(+), 54 deletions(-) diff --git a/chicago/models.py b/chicago/models.py index 765204f..7d8ca3e 100644 --- a/chicago/models.py +++ b/chicago/models.py @@ -126,7 +126,7 @@ def addresses(self): return [] - @property + @cached_property def full_text_doc_url(self): """ override this if instead of having full text as string stored in @@ -175,26 +175,7 @@ def most_recent_past_city_council_meeting(cls): else: return None - @property - def clean_agenda_items(self): - - sponsors = BillSponsorship.objects.filter(entity_type="person").select_related( - "person__councilmatic_person" - ) - related_bill = ( - EventRelatedEntity.objects.filter(entity_type="bill") - .select_related("bill__councilmatic_bill") - .prefetch_related( - Prefetch("bill__sponsorships", queryset=sponsors, to_attr="sponsors") - ) - ) - agenda_items = self.agenda.order_by("order").prefetch_related( - Prefetch("related_entities", queryset=related_bill, to_attr="bills") - ) - - return agenda_items - - @property + @cached_property def video_vimeo_id(self): try: link = self.media.first().links.first().url diff --git a/chicago/templates/event.html b/chicago/templates/event.html index 6bf058d..8ccb778 100644 --- a/chicago/templates/event.html +++ b/chicago/templates/event.html @@ -30,7 +30,7 @@

    {%if event.status == 'cancelled'%}CANCELLED: {% endif %}{{event.name}}


    - {% if event.clean_agenda_items %} + {% if event.agenda.all %}

    Agenda

    @@ -42,7 +42,7 @@

    Agenda

    - {% for agenda_item in event.clean_agenda_items %} + {% for agenda_item in event.agenda.all %} {% if agenda_item.description|lower != 'page break' %} diff --git a/chicago/templates/legislation.html b/chicago/templates/legislation.html index d44ca92..73e56ce 100644 --- a/chicago/templates/legislation.html +++ b/chicago/templates/legislation.html @@ -30,7 +30,7 @@


    {{ legislation.title }}

    - {% if legislation.other_identifiers %} + {% if legislation.other_identifiers.all %}

    Alternate identifiers: {% for identifier in legislation.other_identifiers.all %} @@ -42,7 +42,7 @@

    - {% if legislation.sponsorships.all %} + {% if legislation.sponsors %}

    Sponsors

    @@ -51,8 +51,8 @@

    Sponsors

    - {% for s in legislation.sponsorships.all %} - {% if s.is_primary %} + {% for s in legislation.sponsors %} + {% if s.primary %} {% endif %} {% endfor %} - {% for s in legislation.sponsorships.all %} - {% if not s.is_primary %} + {% for s in legislation.sponsors %} + {% if not s.primary %} {% endif %} @@ -103,7 +103,7 @@

    Sponsors

    {% endif %} - {% if actions %} + {% if legislation.actions %}

    History

    {{ forloop.counter }}
    - {% if legislation.sponsorships.all|length > 1 %} - Sponsors ({{legislation.sponsorships.all|length}}) + {% if legislation.sponsors.all|length > 1 %} + Sponsors ({{legislation.sponsors.all|length}}) {% else %} Sponsor {% endif %} @@ -63,36 +63,36 @@

    Sponsors

    - {{s.person.name}} + {{s.person.name}}
    - {{ s.person.link_html | safe }} Primary Sponsor + {{ s.person.name }}Primary Sponsor - {{s.person.latest_council_membership.post.label}} + {{s.person.council_posts.0.post.label}}
    - {{s.person.name}} + {{s.person.name}}
    - {{ s.person.link_html | safe }} + {{ s.person.name }} - {{s.person.latest_council_membership.post.label}} + {{s.person.council_posts.0.post.label}}
    @@ -115,7 +115,7 @@

    History

    - {% for action in actions %} + {% for action in legislation.actions.all %} - {% for s in legislation.sponsors %} + {% for s in sponsors %} {% if s.primary %} {% endif %} {% endfor %} - {% for s in legislation.sponsors %} + {% for s in sponsors %} {% if not s.primary %}
    {{action.date}} @@ -215,7 +215,7 @@

    Upcoming {{ CITY_VOCAB.EVENTS }}

    {% for event in legislation.unique_related_upcoming_events %}

    - {{event.start_time | date:'M d, Y' }} - {{event.link_html | safe}} + {{event.start_time | date:'M d, Y' }} - {{ event.name }}

    {% endfor %} @@ -278,7 +278,7 @@

    Legislation not found

    "sourceOrganization": "{{ CITY_COUNCIL_NAME }}", "name": "{{ legislation.friendly_name }}", "alternateName": ["{{ legislation.identifier }}", "{{ legislation.identifier.split|join:'' }}"], - {% if actions %}"datePublished": "{{actions.0.date|date:'Y-m-d'}}", {% endif %} + {% if legislation.actions %}"datePublished": "{{legislation.actions.0.date|date:'Y-m-d'}}", {% endif %} "description": "{{ legislation.description }}", "text": "{% firstof legislation.full_text legislation.ocr_full_text %}" } diff --git a/chicago/views.py b/chicago/views.py index 62b3962..e2bf656 100644 --- a/chicago/views.py +++ b/chicago/views.py @@ -4,15 +4,13 @@ from urllib.parse import urlencode import pytz -from councilmatic_core.models import Organization, Post +from councilmatic_core.models import BillAction, Organization, Post from councilmatic_core.views import ( AboutView, - BillDetailView, CommitteeDetailView, CommitteesView, CouncilmaticSearchForm, CouncilMembersView, - EventDetailView, EventsView, IndexView, PersonDetailView, @@ -24,9 +22,16 @@ from django.http import Http404, HttpResponsePermanentRedirect from django.urls import reverse from django.utils import timezone -from django.views.generic import ListView, DetailView +from django.views.generic import DetailView, ListView from haystack.generic_views import FacetedSearchView -from opencivicdata.legislative.models import LegislativeSession, PersonVote +from opencivicdata.core.models import Membership +from opencivicdata.legislative.models import ( + BillSponsorship, + EventAgendaItem, + EventRelatedEntity, + LegislativeSession, + PersonVote, +) from chicago.models import ChicagoBill, ChicagoEvent, ChicagoOrganization, ChicagoPerson @@ -227,13 +232,11 @@ def get(self, request, *args, **kwargs): except self.model.DoesNotExist: raise Http404 - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - - bill = self.object + def get_queryset(self): - context["actions"] = ( - bill.actions.order_by("-order") + # Getting a handle on vote details + actions_qs = ( + BillAction.objects.order_by("-order") .select_related("organization__councilmatic_organization") .select_related("vote") .prefetch_related( @@ -246,6 +249,37 @@ def get_context_data(self, **kwargs): ) ) + # Getting a handle on sponsors and council posts + sponsorships_qs = ( + BillSponsorship.objects.filter(person_id__isnull=False) + .select_related("person__councilmatic_person") + .prefetch_related( + Prefetch( + "person__memberships", + queryset=Membership.objects.filter( + organization__name=settings.OCD_CITY_COUNCIL_NAME + ) + .order_by("-start_date", "-end_date") + .select_related("post"), + to_attr="council_posts", + ) + ) + ) + + return ( + super() + .get_queryset() + .prefetch_related(Prefetch("actions", queryset=actions_qs)) + .prefetch_related( + Prefetch("sponsorships", queryset=sponsorships_qs, to_attr="sponsors") + ) + ) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + bill = self.object + seo = {} seo.update(settings.SITE_META) seo["site_desc"] = bill.listing_description @@ -490,12 +524,13 @@ def get_context_data(self, **kwargs): return context -class ChicagoEventDetailView(EventDetailView): +class ChicagoEventDetailView(DetailView): model = ChicagoEvent template_name = "event.html" + context_object_name = "event" def get_context_data(self, **kwargs): - context = super(EventDetailView, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) event = context["event"] # getting expected attendees and actual attendees @@ -540,3 +575,28 @@ def get_context_data(self, **kwargs): context["seo"] = seo return context + + def get_queryset(self): + + sponsors_qs = BillSponsorship.objects.filter( + person_id__isnull=False + ).select_related("person__councilmatic_person") + + related_bill_qs = ( + EventRelatedEntity.objects.filter(entity_type="bill") + .select_related("bill__councilmatic_bill") + .prefetch_related( + Prefetch("bill__sponsorships", queryset=sponsors_qs, to_attr="sponsors") + ) + ) + + agenda_items_qs = EventAgendaItem.objects.order_by("order").prefetch_related( + Prefetch("related_entities", queryset=related_bill_qs, to_attr="bills") + ) + + return ( + super() + .get_queryset() + .prefetch_related(Prefetch("agenda", queryset=agenda_items_qs)) + .prefetch_related("documents") + ) From eb6a8ffb0eff19ac5f1d4fa18e853210700c4cf5 Mon Sep 17 00:00:00 2001 From: Forest Gregg Date: Sun, 10 Sep 2023 01:10:53 -0400 Subject: [PATCH 6/8] make the ward labels a bit tighter --- chicago/templates/legislation.html | 18 +++++++----- chicago/views.py | 44 ++++++++++++++++++------------ 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/chicago/templates/legislation.html b/chicago/templates/legislation.html index 73e56ce..c7c4858 100644 --- a/chicago/templates/legislation.html +++ b/chicago/templates/legislation.html @@ -30,19 +30,22 @@


    {{ legislation.title }}

    - {% if legislation.other_identifiers.all %} + {% with other_identifiers=legislation.other_identifiers.all %} + {% if other_identifiers %}

    Alternate identifiers: - {% for identifier in legislation.other_identifiers.all %} + {% for identifier in other_identifiers %} {{ identifier.identifier }} {% if not forloop.last %} , {% endif %} {% endfor %}

    {% endif %} + {% endwith %}
    - {% if legislation.sponsors %} + {% with sponsors=sponsors_qs.all %} + {% if sponsors %}

    Sponsors

    @@ -51,8 +54,8 @@

    Sponsors

    - {% if legislation.sponsors.all|length > 1 %} - Sponsors ({{legislation.sponsors.all|length}}) + {% if sponsors|length > 1 %} + Sponsors ({{sponsors|length}}) {% else %} Sponsor {% endif %} @@ -63,7 +66,7 @@

    Sponsors

    @@ -80,7 +83,7 @@

    Sponsors

    @@ -102,6 +105,7 @@

    Sponsors

    {% endif %} + {% endwith %} {% if legislation.actions %}

    History

    diff --git a/chicago/views.py b/chicago/views.py index e2bf656..59fa483 100644 --- a/chicago/views.py +++ b/chicago/views.py @@ -18,7 +18,7 @@ from dateutil import parser from dateutil.relativedelta import relativedelta from django.conf import settings -from django.db.models import Max, Min, Prefetch +from django.db.models import Max, Min, Prefetch, Subquery from django.http import Http404, HttpResponsePermanentRedirect from django.urls import reverse from django.utils import timezone @@ -247,17 +247,37 @@ def get_queryset(self): ), ) ) + .prefetch_related("vote__counts") ) - # Getting a handle on sponsors and council posts - sponsorships_qs = ( - BillSponsorship.objects.filter(person_id__isnull=False) + return ( + super() + .get_queryset() + .prefetch_related(Prefetch("actions", queryset=actions_qs)) + ) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + bill = self.object + + # we have to do the sponsors here, instead of in get_queryset + # because we need a handle on the actual bill object in order + # to get the council post as of the first action on the bill + first_action_date_subquery = ( + BillAction.objects.filter(bill_id=bill).order_by("order").values("date")[:1] + ) + + sponsors = ( + bill.sponsorships.filter(person_id__isnull=False) .select_related("person__councilmatic_person") .prefetch_related( Prefetch( "person__memberships", queryset=Membership.objects.filter( - organization__name=settings.OCD_CITY_COUNCIL_NAME + organization__name=settings.OCD_CITY_COUNCIL_NAME, + start_date__lte=Subquery(first_action_date_subquery), + end_date__gte=Subquery(first_action_date_subquery), ) .order_by("-start_date", "-end_date") .select_related("post"), @@ -266,19 +286,7 @@ def get_queryset(self): ) ) - return ( - super() - .get_queryset() - .prefetch_related(Prefetch("actions", queryset=actions_qs)) - .prefetch_related( - Prefetch("sponsorships", queryset=sponsorships_qs, to_attr="sponsors") - ) - ) - - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - - bill = self.object + context["sponsors_qs"] = sponsors seo = {} seo.update(settings.SITE_META) From ebf7d480baac0550fb777c9a4563c42a261e36b1 Mon Sep 17 00:00:00 2001 From: Derek Eder Date: Mon, 11 Sep 2023 14:08:39 -0500 Subject: [PATCH 7/8] updated event layout into one column --- chicago/templates/event.html | 39 ++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/chicago/templates/event.html b/chicago/templates/event.html index 8ccb778..30c06d3 100644 --- a/chicago/templates/event.html +++ b/chicago/templates/event.html @@ -28,10 +28,10 @@

    {%if event.status == 'cancelled'%}CANCELLED: {% endif %}{{event.name}}

    View on Vimeo

    {% endif %}
    -
    -
    +
    +
    {% if event.agenda.all %} -

    Agenda

    +

    Agenda: {{event.agenda.all|length}} items

    @@ -55,7 +55,7 @@

    Agenda

    {% else %} @@ -69,24 +69,10 @@

    Agenda

    {% for s in agenda_item.bills.0.bill.sponsors %} - {{ s.person.councilmatic_person.link_html | safe }}{% if not forloop.last %},{% endif %} + {{ s.person.councilmatic_person.link_html | safe }}{% if not forloop.last %},{% endif %} {% endfor %}
    {% endif %} - {% if event.documents.all %} -

    Attachments

    -

    - {% for document in event.documents.all %} - {{document.note}}
    - {% endfor %} -

    - {% endif %} - -
    -
    {% if event.status == 'passed' %} {% if attendance_taken %} -

    Attendance: {{attendance_present}} Present, {{attendance_absent}} Absent

    +

    Alder Attendance: {{attendance_present}} Present, {{attendance_absent}} Absent

    @@ -110,10 +96,23 @@

    Attendance: {{attendance_present}} Present, {{attendance_absent}} Absent

    {% else %} -

    Attendance

    +

    Alder Attendance

    Attendance was not taken for this meeting or has not been posted by the Clerk's office

    {% endif %} {% endif %} + + {% if event.documents.all %} +

    Attachments

    +

    + {% for document in event.documents.all %} + {{document.note}}
    + {% endfor %} +

    + {% endif %} + From 7fff7229bc7b1efcccb784d11bf2c89df1f711a4 Mon Sep 17 00:00:00 2001 From: Derek Eder Date: Mon, 11 Sep 2023 14:11:15 -0500 Subject: [PATCH 8/8] remove print statement --- chicago/models.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/chicago/models.py b/chicago/models.py index 7d8ca3e..fcc1972 100644 --- a/chicago/models.py +++ b/chicago/models.py @@ -7,12 +7,9 @@ from dateutil.relativedelta import relativedelta from django.conf import settings from django.db import models -from django.db.models import Prefetch from django.utils import timezone from django.utils.functional import cached_property -from opencivicdata.legislative.models import (BillSponsorship, - EventRelatedEntity, - LegislativeSession) +from opencivicdata.legislative.models import LegislativeSession from .helpers import topic_classifier @@ -180,7 +177,6 @@ def video_vimeo_id(self): try: link = self.media.first().links.first().url vimeo_id = re.match(".*?([0-9]+)$", link).group(1) - print(link, vimeo_id) return vimeo_id except AttributeError: return None