diff --git a/wcivf/apps/elections/managers.py b/wcivf/apps/elections/managers.py index b62b99993..2658e88fe 100644 --- a/wcivf/apps/elections/managers.py +++ b/wcivf/apps/elections/managers.py @@ -1,4 +1,5 @@ from django.db import models +from django.db.models import Sum, Count from django.utils import timezone from .helpers import EEHelper @@ -22,8 +23,6 @@ def past(self): """ return self.filter(current=False, election_date__lt=timezone.now()) - -class ElectionManager(models.Manager.from_queryset(ElectionQuerySet)): def get_explainer(self, election): ee = EEHelper() ee_data = ee.get_data(election["id"]) @@ -62,11 +61,16 @@ def election_id_to_type(self, election_id): parts = election_id.split(".") return parts[0] - def past(self): + def parties(self): """ - Allows past method on QuerySet object to be called directly from the manager + Return a list of party models that are standing in this election """ - return self.get_queryset().past() + + return ( + self.values("postelection__personpost__party") + .annotate(count=Count("postelection__personpost__party")) + .order_by("-postelection__personpost__party") + ) class PostManager(models.Manager): @@ -104,3 +108,8 @@ def update_or_create_from_ynr(self, post_dict): ) return (post, created) + + +class PostElectionQueryset(models.QuerySet): + def seats_total(self): + return self.aggregate(sum=Sum("winner_count"))["sum"] diff --git a/wcivf/apps/elections/models.py b/wcivf/apps/elections/models.py index 62c0b9bb6..fe4ed68cb 100644 --- a/wcivf/apps/elections/models.py +++ b/wcivf/apps/elections/models.py @@ -1,5 +1,7 @@ import datetime import re + +from django.db.models import Count from django.utils import timezone import pytz @@ -14,7 +16,7 @@ from django.utils.text import slugify from .helpers import get_election_timetable -from .managers import ElectionManager +from .managers import PostElectionQueryset, ElectionQuerySet LOCAL_TZ = pytz.timezone("Europe/London") @@ -46,7 +48,7 @@ class Election(models.Model): metadata = JSONField(null=True) any_non_by_elections = models.BooleanField(default=False) - objects = ElectionManager() + objects = ElectionQuerySet.as_manager() class Meta: ordering = ["election_date"] @@ -220,6 +222,24 @@ def pluralized_division_name(self): return pluralise.get(suffix, f"{suffix}s") + def parties(self): + parties_with_counts = { + d["personpost__party__party_id"]: { + "count": d["personpost__party__count"] + } + for d in self.postelection_set.values("personpost__party__party_id") + .annotate(Count("personpost__party")) + .order_by("-personpost__party") + } + from parties.models import Party + + party_model_qs = Party.objects.filter( + party_id__in=parties_with_counts.keys() + ) + for party in party_model_qs: + parties_with_counts[party.party_id]["party"] = party + return parties_with_counts + class Post(models.Model): """ @@ -335,6 +355,8 @@ class PostElection(models.Model): wikipedia_url = models.CharField(blank=True, null=True, max_length=800) wikipedia_bio = models.TextField(null=True) + objects = PostElectionQueryset.as_manager() + @property def expected_sopn_date(self): try: diff --git a/wcivf/apps/elections/templates/elections/election_view.html b/wcivf/apps/elections/templates/elections/election_view.html index 556629f54..ac19b4e1e 100644 --- a/wcivf/apps/elections/templates/elections/election_view.html +++ b/wcivf/apps/elections/templates/elections/election_view.html @@ -1,5 +1,5 @@ {% extends "base.html" %} - +{% load markdown_deux_tags %} {% load breadcrumb_tags %} {% load humanize %} @@ -8,44 +8,68 @@ {% block og_description %}The {{ object.name }} {% if object.in_past %}was{% else %}will be{% endif %} held on {{ object.election_date }}.{% endblock og_description %} {% block content %} +
The {{ object.nice_election_name }} - {% if object.is_election_day %} - is being held today. - Polls are open from {{ object.polls_open|time:"ga" }} till {{ object.polls_close|time:"ga" }} - {% else %} - {% if object.in_past %}was{% else %}will be{% endif %} held {{ object.election_date|naturalday:"\o\n l j F Y" }}. - {% endif %} -
+The {{ object.nice_election_name }} + {% if object.is_election_day %} + is being held today. + Polls are open from {{ object.polls_open|time:"ga" }} till {{ object.polls_close|time:"ga" }} + {% else %} + {% if object.in_past %}was{% else %}will be{% endif %} held {{ object.election_date|naturalday:"\o\n l j F Y" }}. + {% endif %} +
- {% if object.election_type != "ref" %} - {% if election.person_set.count %} -{% if object.locked %}There are {% else %}We know about {% endif %}{{ election.person_set.count }} candidates + {% if object.election_type != "ref" %} + {% if election.personpost_set.count %} +
{% if object.locked %}There are {% else %}We know about {% endif %}{{ election.personpost_set.count }} candidates {% if object.in_past %}that stood{% else %}standing{% endif %} for this election, - in {{ object.post_set.count }} posts.
- {% if not object.in_past and not object.locked %} -Add more at our candidate crowd-sourcing site
- {% endif %} - {% else %} - {% if not object.in_past and not election.slug == 'parl.2017-06-08' %} -Add some candidates at our candidate crowd-sourcing site
- {% endif %} + in {{ object.postelection_set.count }} {{ object.pluralized_division_name }}. {% endif %} -{{ object.parties.keys|length }} parties are contesting {{ object.postelection_set.seats_total }} seats across {{ object.postelection_set.count }} {{ object.pluralized_division_name }}.
+| Name | +Candidates | +Seats | +
|---|---|---|
| {{ postelection.post.label }} + {{ postelection.short_cancelled_message_html }} | +{{ postelection.personpost_set.count }} | +{{ postelection.winner_count }} | + +