diff --git a/peachjam/admin.py b/peachjam/admin.py index b69fa81b7..81d98e212 100644 --- a/peachjam/admin.py +++ b/peachjam/admin.py @@ -49,11 +49,13 @@ Book, CaseHistory, CaseNumber, + CauseList, CitationLink, CitationProcessing, CoreDocument, Court, CourtClass, + CourtDivision, CourtRegistry, DocumentNature, DocumentTopic, @@ -1014,6 +1016,13 @@ def upload_view(self, request): return render(request, "admin/judgment_upload_form.html", context) +@admin.register(CauseList) +class CauseListAdmin(DocumentAdmin): + fieldsets = copy.deepcopy(DocumentAdmin.fieldsets) + fieldsets[0][1]["fields"].insert(3, "court") + fieldsets[0][1]["fields"].insert(3, "judges") + + @admin.register(Predicate) class PredicateAdmin(admin.ModelAdmin): list_display = ("name",) @@ -1362,6 +1371,7 @@ class AttorneyAdmin(ImportExportMixin, admin.ModelAdmin): [ CitationLink, CourtClass, + CourtDivision, AttachedFileNature, CitationProcessing, Folder, diff --git a/peachjam/migrations/0168_courtdivision_alter_coredocument_doc_type_causelist.py b/peachjam/migrations/0168_courtdivision_alter_coredocument_doc_type_causelist.py new file mode 100644 index 000000000..c0ccc031b --- /dev/null +++ b/peachjam/migrations/0168_courtdivision_alter_coredocument_doc_type_causelist.py @@ -0,0 +1,117 @@ +# Generated by Django 4.2.16 on 2024-10-16 15:08 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("peachjam", "0167_peachjamsettings_allow_social_logins"), + ] + + operations = [ + migrations.CreateModel( + name="CourtDivision", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "name", + models.CharField(max_length=255, unique=True, verbose_name="name"), + ), + ( + "code", + models.SlugField(max_length=255, unique=True, verbose_name="code"), + ), + ( + "order", + models.IntegerField(blank=True, null=True, verbose_name="order"), + ), + ], + ), + migrations.AlterField( + model_name="coredocument", + name="doc_type", + field=models.CharField( + choices=[ + ("core_document", "Core Document"), + ("gazette", "Gazette"), + ("generic_document", "Generic Document"), + ("judgment", "Judgment"), + ("legal_instrument", "Legal Instrument"), + ("legislation", "Legislation"), + ("book", "Book"), + ("journal", "Journal"), + ("causelist", "Cause List"), + ], + default="core_document", + max_length=255, + verbose_name="document type", + ), + ), + migrations.CreateModel( + name="CauseList", + fields=[ + ( + "coredocument_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="peachjam.coredocument", + ), + ), + ( + "court", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="causelists", + to="peachjam.court", + verbose_name="court", + ), + ), + ( + "division", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="causelists", + to="peachjam.courtdivision", + ), + ), + ( + "judges", + models.ManyToManyField( + blank=True, to="peachjam.judge", verbose_name="judges" + ), + ), + ( + "registry", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="causelists", + to="peachjam.courtregistry", + ), + ), + ], + options={ + "abstract": False, + "base_manager_name": "objects", + }, + bases=("peachjam.coredocument",), + ), + ] diff --git a/peachjam/models/core_document_model.py b/peachjam/models/core_document_model.py index fd724e0e6..92c254860 100644 --- a/peachjam/models/core_document_model.py +++ b/peachjam/models/core_document_model.py @@ -326,6 +326,7 @@ class CoreDocument(PolymorphicModel): ("legislation", "Legislation"), ("book", "Book"), ("journal", "Journal"), + ("causelist", "Cause List"), ) # The name of the default nature to use for this type of document, if one is not set. This allows us to ensure diff --git a/peachjam/models/judgment.py b/peachjam/models/judgment.py index a59365b15..68d72a83e 100644 --- a/peachjam/models/judgment.py +++ b/peachjam/models/judgment.py @@ -115,6 +115,23 @@ def save(self, *args, **kwargs): return super().save(*args, **kwargs) +class CourtDivision(models.Model): + name = models.CharField(_("name"), max_length=255, null=False, unique=True) + code = models.SlugField(_("code"), max_length=255, null=False, unique=True) + entity_profile = GenericRelation( + "peachjam.EntityProfile", verbose_name=_("profile") + ) + order = models.IntegerField(_("order"), null=True, blank=True) + + def __str__(self): + return self.name + + def save(self, *args, **kwargs): + if not self.code: + self.code = slugify(self.name) + return super().save(*args, **kwargs) + + class Court(models.Model): name = models.CharField(_("name"), max_length=255, null=False, unique=True) code = models.SlugField(_("code"), max_length=255, null=False, unique=True) @@ -539,3 +556,45 @@ def __str__(self): elif self.case_number: return f"{self.case_number}" return _("Case history") + + +class CauseList(CoreDocument): + frbr_uri_doctypes = ["doc"] + default_nature = ("causelist", "Cause list") + court = models.ForeignKey( + Court, + on_delete=models.PROTECT, + null=True, + verbose_name=_("court"), + related_name="causelists", + ) + registry = models.ForeignKey( + CourtRegistry, + on_delete=models.PROTECT, + null=True, + related_name="causelists", + blank=True, + ) + division = models.ForeignKey( + CourtDivision, + on_delete=models.PROTECT, + null=True, + related_name="causelists", + blank=True, + ) + judges = models.ManyToManyField(Judge, blank=True, verbose_name=_("judges")) + + def assign_title(self): + court_name = self.registry.name if self.registry else "" + if not self.registry: + court_name = self.court.name if self.court else "" + nature_name = self.nature.name if self.nature else "" + date_str = self.date.strftime("%d %B %Y") + + self.title = f"{court_name} - {nature_name} - {date_str}" + + def pre_save(self): + self.assign_title() + self.frbr_uri_doctype = "doc" + self.doc_type = "causelist" + super().pre_save() diff --git a/peachjam/templates/peachjam/_causelist_court_class_month_list.html b/peachjam/templates/peachjam/_causelist_court_class_month_list.html new file mode 100644 index 000000000..001b72dc0 --- /dev/null +++ b/peachjam/templates/peachjam/_causelist_court_class_month_list.html @@ -0,0 +1,11 @@ +{% extends "peachjam/_court_months_list.html" %} +{% load i18n %} +{% block month_link %} + {{ m|date:"F" }} +{% endblock %} +{% block month_option %} + +{% endblock %} diff --git a/peachjam/templates/peachjam/_causelist_court_class_years_list.html b/peachjam/templates/peachjam/_causelist_court_class_years_list.html new file mode 100644 index 000000000..9fee7c49f --- /dev/null +++ b/peachjam/templates/peachjam/_causelist_court_class_years_list.html @@ -0,0 +1,11 @@ +{% extends "peachjam/_court_years_list.html" %} +{% load i18n %} +{% block year_link %} + {{ y.year }} +{% endblock %} +{% block year_option %} + +{% endblock %} diff --git a/peachjam/templates/peachjam/_causelist_court_list.html b/peachjam/templates/peachjam/_causelist_court_list.html new file mode 100644 index 000000000..97d336e18 --- /dev/null +++ b/peachjam/templates/peachjam/_causelist_court_list.html @@ -0,0 +1,8 @@ +{% extends "peachjam/_court_list.html" %} +{% load i18n %} +{% block court_class_link %} + {% trans 'All causelists' %} +{% endblock %} +{% block court_link %} + {{ court.name }} +{% endblock %} diff --git a/peachjam/templates/peachjam/_causelist_court_months_list.html b/peachjam/templates/peachjam/_causelist_court_months_list.html new file mode 100644 index 000000000..339ec8a00 --- /dev/null +++ b/peachjam/templates/peachjam/_causelist_court_months_list.html @@ -0,0 +1,10 @@ +{% extends "peachjam/_court_months_list.html" %} +{% load i18n %} +{% block month_link %} + {{ m|date:"F" }} +{% endblock %} +{% block month_option %} + +{% endblock %} diff --git a/peachjam/templates/peachjam/_causelist_court_registries_months_list.html b/peachjam/templates/peachjam/_causelist_court_registries_months_list.html new file mode 100644 index 000000000..95dd5b7b0 --- /dev/null +++ b/peachjam/templates/peachjam/_causelist_court_registries_months_list.html @@ -0,0 +1,11 @@ +{% extends "peachjam/_court_months_list.html" %} +{% load i18n %} +{% block month_link %} + {{ m|date:"F" }} +{% endblock %} +{% block month_option %} + +{% endblock %} diff --git a/peachjam/templates/peachjam/_causelist_court_registries_years_list.html b/peachjam/templates/peachjam/_causelist_court_registries_years_list.html new file mode 100644 index 000000000..be54df368 --- /dev/null +++ b/peachjam/templates/peachjam/_causelist_court_registries_years_list.html @@ -0,0 +1,11 @@ +{% extends "peachjam/_court_years_list.html" %} +{% load i18n %} +{% block year_link %} + {{ y.year }} +{% endblock %} +{% block year_option %} + +{% endblock %} diff --git a/peachjam/templates/peachjam/_causelist_court_years_list.html b/peachjam/templates/peachjam/_causelist_court_years_list.html new file mode 100644 index 000000000..f991468bd --- /dev/null +++ b/peachjam/templates/peachjam/_causelist_court_years_list.html @@ -0,0 +1,11 @@ +{% extends "peachjam/_court_years_list.html" %} +{% load i18n %} +{% block year_link %} + {{ y.year }} +{% endblock %} +{% block year_option %} + +{% endblock %} diff --git a/peachjam/templates/peachjam/_court_list.html b/peachjam/templates/peachjam/_court_list.html index f32ec9b42..443f587cb 100644 --- a/peachjam/templates/peachjam/_court_list.html +++ b/peachjam/templates/peachjam/_court_list.html @@ -6,14 +6,18 @@

{{ court_class }}

{% if court_class.show_listing_page %}
- {% trans 'All judgments' %} + {% block court_class_link %} + {% trans 'All judgments' %} + {% endblock %}
{% endif %} {% if court_class.courts.all %} diff --git a/peachjam/templates/peachjam/causelist_court_class_detail.html b/peachjam/templates/peachjam/causelist_court_class_detail.html new file mode 100644 index 000000000..48845f0b3 --- /dev/null +++ b/peachjam/templates/peachjam/causelist_court_class_detail.html @@ -0,0 +1,8 @@ +{% extends 'peachjam/causelist_court_detail.html' %} +{% load i18n %} +{% block year_list %} + {% include "peachjam/_causelist_court_class_years_list.html" %} +{% endblock %} +{% block month_list %} + {% include "peachjam/_causelist_court_class_month_list.html" %} +{% endblock %} diff --git a/peachjam/templates/peachjam/causelist_court_detail.html b/peachjam/templates/peachjam/causelist_court_detail.html new file mode 100644 index 000000000..4bb57cf14 --- /dev/null +++ b/peachjam/templates/peachjam/causelist_court_detail.html @@ -0,0 +1,46 @@ +{% extends 'peachjam/layouts/document_list.html' %} +{% load i18n %} +{% block title %}{{ page_title }}{% endblock %} +{% block breadcrumbs %} +
+ +
+{% endblock %} +{% block page-title %} + {% if not entity_profile %}

{{ page_title }}

{% endif %} +{% endblock %} +{% block page-header %} + {{ block.super }} + {% block court_list %} + {% include 'peachjam/_registries.html' %} + {% endblock %} + {% block year_list %} + {% include 'peachjam/_causelist_court_years_list.html' %} + {% endblock %} + {% block month_list %} + {% include 'peachjam/_causelist_court_months_list.html' %} + {% endblock %} +{% endblock %} diff --git a/peachjam/templates/peachjam/causelist_court_registry_detail.html b/peachjam/templates/peachjam/causelist_court_registry_detail.html new file mode 100644 index 000000000..82bbd31c1 --- /dev/null +++ b/peachjam/templates/peachjam/causelist_court_registry_detail.html @@ -0,0 +1,8 @@ +{% extends 'peachjam/causelist_court_detail.html' %} +{% load i18n %} +{% block year_list %} + {% include "peachjam/_causelist_court_registries_years_list.html" %} +{% endblock %} +{% block month_list %} + {% include "peachjam/_causelist_court_registries_months_list.html" %} +{% endblock %} diff --git a/peachjam/templates/peachjam/causelist_detail.html b/peachjam/templates/peachjam/causelist_detail.html new file mode 100644 index 000000000..50a777390 --- /dev/null +++ b/peachjam/templates/peachjam/causelist_detail.html @@ -0,0 +1,53 @@ +{% extends 'peachjam/layouts/document_detail.html' %} +{% load i18n %} +{% block breadcrumbs %} +
+ +
+{% endblock %} +{% block document-metadata-content-citation %} + {{ block.super }} + {% if document.court %} +
+ {% trans 'Court' %} +
+
+ {{ document.court.name }} +
+ {% endif %} + {% if document.registry %} +
+ {{ document.registry.model_label }} +
+
+ {{ document.registry.name }} +
+ {% endif %} + {% if document.division %} +
+ {% trans 'Division' %} +
+
+ {{ document.division.name }} +
+ {% endif %} +{% endblock %} diff --git a/peachjam/templates/peachjam/causelist_list.html b/peachjam/templates/peachjam/causelist_list.html new file mode 100644 index 000000000..c5db472ef --- /dev/null +++ b/peachjam/templates/peachjam/causelist_list.html @@ -0,0 +1,19 @@ +{% extends "peachjam/layouts/document_list.html" %} +{% load i18n %} +{% block title %} + {% trans 'Cause Lists' %} +{% endblock %} +{% block page-title %} +

{% trans 'Cause Lists' %}

+{% endblock %} +{% block document-table %} + {% include 'peachjam/_causelist_court_list.html' %} +

+ {% if title %} + {{ title }} + {% else %} + {% trans 'Recent Cause Lists' %} + {% endif %} +

+ {% include 'peachjam/_recent_document_list.html' with documents=recent_causelists %} +{% endblock %} diff --git a/peachjam/urls.py b/peachjam/urls.py index 20447873d..a85ecf75f 100644 --- a/peachjam/urls.py +++ b/peachjam/urls.py @@ -36,6 +36,16 @@ ArticleYearArchiveView, AuthorDetailView, BookListView, + CauseListCourtClassMonthView, + CauseListCourtClassView, + CauseListCourtClassYearView, + CauseListCourtDetailView, + CauseListCourtMonthView, + CauseListCourtRegistryDetailView, + CauseListCourtRegistryMonthView, + CauseListCourtRegistryYearView, + CauseListCourtYearView, + CauseListListView, CourtClassDetailView, CourtClassMonthView, CourtClassYearView, @@ -154,6 +164,52 @@ CourtRegistryMonthView.as_view(), name="court_registry_month", ), + path("causelists/", CauseListListView.as_view(), name="causelist_list"), + path( + "causelists//", + CauseListCourtDetailView.as_view(), + name="causelist_court", + ), + path( + "causelists/court-class//", + CauseListCourtClassView.as_view(), + name="causelist_court_class", + ), + path( + "causelists/court-class///", + CauseListCourtClassYearView.as_view(), + name="causelist_court_class_year", + ), + path( + "causelists/court-class////", + CauseListCourtClassMonthView.as_view(), + name="causelist_court_class_month", + ), + path( + "causelists///", + CauseListCourtYearView.as_view(), + name="causelist_court_year", + ), + path( + "causelists////", + CauseListCourtMonthView.as_view(), + name="causelist_court_month", + ), + path( + "causelists///", + CauseListCourtRegistryDetailView.as_view(), + name="causelist_court_registry", + ), + path( + "causelists////", + CauseListCourtRegistryYearView.as_view(), + name="causelist_court_registry_year", + ), + path( + "causelists/////", + CauseListCourtRegistryMonthView.as_view(), + name="causelist_court_registry_month", + ), path("place/", PlaceDetailView.as_view(), name="place"), path("legislation/", LegislationListView.as_view(), name="legislation_list"), path( diff --git a/peachjam/views/__init__.py b/peachjam/views/__init__.py index 8bcd1be79..3d0d6afed 100644 --- a/peachjam/views/__init__.py +++ b/peachjam/views/__init__.py @@ -5,6 +5,7 @@ from .authors import * from .autocomplete import * from .books import * +from .causelist import * from .courts import * from .document_nature import * from .document_problem import * diff --git a/peachjam/views/causelist.py b/peachjam/views/causelist.py new file mode 100644 index 000000000..c200bb8fd --- /dev/null +++ b/peachjam/views/causelist.py @@ -0,0 +1,295 @@ +from functools import cached_property +from math import ceil + +from django.shortcuts import get_object_or_404 +from django.urls import reverse +from django.utils.text import gettext_lazy as _ +from django.views.generic import TemplateView + +from peachjam.helpers import lowercase_alphabet +from peachjam.models import ( + CauseList, + Court, + CourtClass, + CourtRegistry, + DocumentNature, + Judge, + Taxonomy, +) +from peachjam.registry import registry +from peachjam.views import BaseDocumentDetailView, FilteredDocumentListView +from peachjam.views.courts import MonthMixin, RegistryMixin +from peachjam.views.generic_views import YearMixin + + +@registry.register_doc_type("causelist") +class CauseListDetailView(BaseDocumentDetailView): + model = CauseList + template_name = "peachjam/causelist_detail.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["judges"] = self.get_object().judges.values_list("name", flat=True) + return context + + +class CauseListListView(TemplateView): + template_name = "peachjam/causelist_list.html" + navbar_link = "causelist" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + context["court_classes"] = CourtClass.objects.prefetch_related("courts") + context["recent_causelists"] = ( + CauseList.objects.select_related("work") + .prefetch_related("labels") + .exclude(published=False) + .order_by("-date")[:30] + ) + context["doc_type"] = "CauseList" + + context["doc_count"] = CauseList.objects.filter(published=True).count() + context["doc_count_noun"] = _("cause list") + context["doc_count_noun_plural"] = _("cause lists") + return context + + +class FilteredCauseListView(FilteredDocumentListView): + """Base List View class for filtering judgments.""" + + model = CauseList + navbar_link = "causelist" + queryset = CauseList.objects.prefetch_related("judges", "labels").select_related( + "work" + ) + group_by_date = "month-year" + exclude_facets = [] + + def base_view_name(self): + return _("CauseList") + + def get_form(self): + self.form_defaults = {"sort": "-date"} + return super().get_form() + + def page_title(self): + return self.base_view_name() + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + context["doc_type"] = "Judgment" + context["page_title"] = self.page_title() + context["doc_table_show_jurisdiction"] = False + context["doc_count_noun"] = _("cause list") + context["doc_count_noun_plural"] = _("cause lists") + + self.populate_years(context) + context["documents"] = self.group_documents(context["documents"]) + + return context + + def add_facets(self, context): + context["facet_data"] = {} + + if "natures" not in self.exclude_facets: + natures = DocumentNature.objects.filter( + pk__in=self.form.filter_queryset( + self.get_base_queryset(), exclude="natures" + ) + .order_by() + .values_list("nature_id", flat=True) + .distinct() + ) + context["facet_data"]["natures"] = { + "label": _("Document nature"), + "type": "radio", + "options": sorted( + [(n.code, n.name) for n in natures], key=lambda x: x[1] + ), + "values": self.request.GET.getlist("natures"), + } + + if "judges" not in self.exclude_facets: + judges = list( + judge + for judge in self.form.filter_queryset( + self.get_base_queryset(), exclude="judges" + ) + .order_by() + .values_list("judges__name", flat=True) + .distinct() + if judge + ) + context["facet_data"]["judges"] = { + "label": Judge.model_label_plural, + "type": "checkbox", + "options": sorted([(j, j) for j in judges]), + "values": self.request.GET.getlist("judges"), + } + + if "taxonomy" not in self.exclude_facets: + taxonomies = Taxonomy.objects.filter( + pk__in=self.form.filter_queryset( + self.get_base_queryset(), exclude="taxonomies" + ) + .filter(taxonomies__topic__isnull=False) + .order_by("taxonomies__topic__id") + .values_list("taxonomies__topic__id", flat=True) + .distinct() + ) + + context["facet_data"]["taxonomies"] = { + "label": _("Topics"), + "type": "checkbox", + "options": sorted( + [(t.slug, t.name) for t in taxonomies], key=lambda x: x[1] + ), + "values": self.request.GET.getlist("taxonomies"), + } + + if "alphabet" not in self.exclude_facets: + context["facet_data"]["alphabet"] = { + "label": _("Alphabet"), + "type": "radio", + "options": [(a, a) for a in lowercase_alphabet()], + "values": self.request.GET.get("alphabet"), + } + + def populate_years(self, context): + context["years"] = self.get_base_queryset(exclude=["year", "month"]).dates( + "date", "year", order="DESC" + ) + + +class CauseListCourtDetailView(FilteredCauseListView): + template_name = "peachjam/causelist_court_detail.html" + + @cached_property + def court(self): + return get_object_or_404(Court, code=self.kwargs["code"]) + + def base_view_name(self): + return f"{self.court.name} {_('Cause Lists')}" + + def get_base_queryset(self, exclude=None): + qs = super().get_base_queryset(exclude=exclude).filter(court=self.court) + return qs + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["court"] = self.court + context["registry_label_plural"] = CourtRegistry.model_label_plural + registries = self.court.registries.exclude(causelists__isnull=True) + split_index = ceil(registries.count() / 2) + for r in registries: + r.get_absolute_url = reverse( + "causelist_court_registry", args=[self.court.code, r.code] + ) + + context["registries"] = registries + context["registry_groups"] = [ + registries[:split_index], + registries[split_index:], + ] + context["all_years_url"] = reverse("causelist_court", args=[self.court.code]) + return context + + +class CauseListCourtYearView(YearMixin, CauseListCourtDetailView): + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["all_months_url"] = reverse( + "causelist_court_year", args=[self.court.code, self.year] + ) + return context + + +class CauseListCourtMonthView(MonthMixin, CauseListCourtYearView): + pass + + +class CauseListCourtRegistryDetailView(RegistryMixin, CauseListCourtDetailView): + template_name = "peachjam/causelist_court_registry_detail.html" + + def base_view_name(self): + return f'{super().base_view_name()} {_("Cause Lists")}' + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["all_years_url"] = reverse( + "causelist_court_registry", args=[self.court.code, self.registry.code] + ) + return context + + +class CauseListCourtRegistryYearView(YearMixin, CauseListCourtRegistryDetailView): + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["all_months_url"] = reverse( + "causelist_court_registry_year", + args=[self.court.code, self.registry.code, self.year], + ) + return context + + +class CauseListCourtRegistryMonthView(MonthMixin, CauseListCourtRegistryYearView): + pass + + +class CauseListCourtClassView(FilteredCauseListView): + template_name = "peachjam/causelist_court_class_detail.html" + + def base_view_name(self): + return f"{self.court_class.name} {_('Cause Lists')}" + + @cached_property + def court_class(self): + return get_object_or_404(CourtClass, slug=self.kwargs["court_class"]) + + def get_base_queryset(self, exclude=None): + qs = ( + super() + .get_base_queryset(exclude=exclude) + .filter(court__court_class=self.court_class) + ) + return qs + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["court_class"] = self.court_class + + context["registries"] = Court.objects.filter(court_class=self.court_class) + context["registry_label_plural"] = _("Courts") + + registries = Court.objects.filter(court_class=self.court_class).exclude( + causelists__isnull=True + ) + for r in registries: + r.get_absolute_url = reverse("causelist_court", args=[r.code]) + + context["registries"] = registries + split_index = ceil(registries.count() / 2) + context["registry_groups"] = [ + registries[:split_index], + registries[split_index:], + ] + context["all_years_url"] = reverse( + "causelist_court_class", args=[self.court_class.slug] + ) + + return context + + +class CauseListCourtClassYearView(YearMixin, CauseListCourtClassView): + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["all_months_url"] = reverse( + "causelist_court_class_year", args=[self.court_class.slug, self.year] + ) + return context + + +class CauseListCourtClassMonthView(MonthMixin, CauseListCourtClassYearView): + pass