Skip to content

Commit

Permalink
Add filters to Uploader CouncilListView
Browse files Browse the repository at this point in the history
  • Loading branch information
GeoWill committed Mar 4, 2024
1 parent 4d874a7 commit 5fdcadb
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 22 deletions.
71 changes: 71 additions & 0 deletions polling_stations/apps/file_uploads/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import django_filters
from councils.models import Council
from dc_utils.filter_widgets import DSLinkWidget
from django.db.models import Exists, OuterRef
from pollingstations.models import PollingStation


class CouncilListUploadFilter(django_filters.FilterSet):
class Meta:
model = Council
fields = [
"name",
"pollingstations",
# "upload",
]

name = django_filters.CharFilter(label="Council Name", method="filter_name")
pollingstations = django_filters.ChoiceFilter(
method="filter_pollingstation",
label="has stations",
widget=DSLinkWidget(),
choices=[
(1, "With Stations"),
(0, "Without Stations"),
],
)
upload = django_filters.ChoiceFilter(
label="uploads",
method="filter_upload",
widget=DSLinkWidget(),
choices=[
("valid", "Valid"),
("invalid", "Invalid"),
("pending", "Pending"),
("no_upload", "No upload"),
],
)

def filter_name(self, queryset, name, value):
return queryset.filter(name__icontains=value)

def filter_pollingstation(self, queryset, name, value):
"""
Filter on whether stations have been imported
"""
pollingstations = PollingStation.objects.filter(council_id=OuterRef("pk"))
if value == "1":
queryset = queryset.filter(Exists(pollingstations))
if value == "0":
queryset = queryset.filter(~Exists(pollingstations))
return queryset

def filter_upload(self, queryset, name, value):
queryset = Council.objects.with_future_upload_details()

if value == "valid":
queryset = queryset.filter(latest_upload_files_valid=True)
if value == "invalid":
queryset = queryset.filter(
latest_upload_files_valid=False, latest_upload_id__isnull=False
)
if value == "pending":
queryset = queryset.filter(
latest_upload_files_valid__isnull=True, latest_upload_id__isnull=False
)
if value == "no_upload":
queryset = queryset.filter(
latest_upload_files_valid__isnull=True, latest_upload_id__isnull=True
)

return queryset
1 change: 0 additions & 1 deletion polling_stations/apps/file_uploads/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ class Upload(models.Model):
timestamp = models.DateTimeField()
election_date = models.DateField(null=True)
github_issue = models.CharField(blank=True, max_length=100)

objects = UploadQuerySet.as_manager()
warning_about_pending_sent = models.BooleanField(default=False)
upload_user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,29 @@
Welcome to Democracy Club’s polling station data uploader. Select a council to upload a file.
If you experience any problems, please contact <a href="mailto:pollingstations@democracyclub.org.uk">pollingstations@democracyclub.org.uk</a>.
</p>
<h1>{% if request.user.is_staff %}
All councils
{% if request.user.is_staff %}
<h1>All councils</h1>
<aside class="ds-filter" aria-labelledby="filter-label">
<details open>
<summary>Filters</summary>
<form>
<div class="ds-filter-cluster">
{% for field in filter.form %}
<ul aria-labelledby="filter-label-{{ forloop.counter }}">
<li id="filter-label-{{ forloop.counter }}" class="ds-filter-label" aria-hidden="true">
{{ field.label }}:
</li>
{{ field }}
</ul>
{% endfor %}
</div>
</form>
</details>
</aside>
{% else %}
Your councils
<h1>Your councils</h1>
{% endif %}
</h1>

{% if object_list %}
<table class="ds-table">
<tr>
Expand All @@ -36,17 +53,24 @@ <h1>{% if request.user.is_staff %}
{% if request.user.is_staff %}
<td><a href="mailto:{{ council.electoral_services_email }}">{{ council.electoral_services_email }}</a></td>
{% endif %}
{% if request.user.is_staff %}<td>
<a href="{% url 'file_uploads:file_upload' gss=council.council_id %}">
upload
</a>
</td>
{% if request.user.is_staff %}
<td>
<a href="{% url 'file_uploads:file_upload' gss=council.council_id %}">
upload
</a>
</td>
{% endif %}
<td>
{{ council.upload_set.future.latest.status_emoji }}
</td>
{% if council in COUNCILS_WITH_STATIONS %}
{% if council.latest_upload_files_valid %}
<td>✔️</td>
{% elif council.latest_upload_files_valid == None and council.latest_upload_id %}
<td></td>
{% elif not council.latest_upload_files_valid and council.latest_upload_id %}
<td></td>
{% else %}
<td></td>
{% endif %}
{% if council.ps_count %}
<td>✔️ <cite><small>({{ council.ps_count }})</small></cite></td>
{% else %}
<td></td>
{% endif %}
Expand Down
23 changes: 15 additions & 8 deletions polling_stations/apps/file_uploads/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from django.contrib.auth.mixins import UserPassesTestMixin
from django.core.exceptions import ValidationError as DjangoValidationError
from django.db import DEFAULT_DB_ALIAS
from django.db.models import Max, Prefetch, Subquery
from django.db.models import Count, Max, Subquery
from django.http import HttpResponseRedirect, JsonResponse
from django.shortcuts import redirect
from django.template.loader import render_to_string
Expand All @@ -29,6 +29,7 @@
from sentry_sdk import capture_message
from sesame.utils import get_query_string, get_user

from .filters import CouncilListUploadFilter
from .models import File, Upload
from .utils import assign_councils_to_user, get_domain

Expand Down Expand Up @@ -186,23 +187,18 @@ def post(self, request, *args, **kwargs):

class CouncilView:
def get_queryset(self):
uploads = Upload.objects.all().order_by("-timestamp")
qs = (
Council.objects.all()
Council.objects.with_future_upload_details()
.exclude(council_id__startswith="N09")
.annotate(ps_count=Count("pollingstation"))
.order_by("name")
.prefetch_related(Prefetch("upload_set", uploads))
.prefetch_related("upload_set__file_set")
)
if not self.request.user.is_staff:
qs = qs.filter(usercouncils__user=self.request.user)
return qs

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context[
"COUNCILS_WITH_STATIONS"
] = Council.objects.with_polling_stations_in_db()

if self.kwargs.get("pk"):
upcoming_election_dates = EveryElectionWrapper(
Expand All @@ -217,6 +213,17 @@ def get_context_data(self, **kwargs):
class CouncilListView(CouncilFileUploadAllowedMixin, CouncilView, ListView):
template_name = "file_uploads/council_list.html"

def get_queryset(self):
queryset = super().get_queryset()
self.filter = CouncilListUploadFilter(self.request.GET, queryset=queryset)
return self.filter.qs

def get_context_data(self, **kwargs):
# Add the filter to the context
context = super().get_context_data(**kwargs)
context["filter"] = self.filter
return context

def get(self, request, *args, **kwargs):
user_councils = self.get_queryset()

Expand Down

0 comments on commit 5fdcadb

Please sign in to comment.