1+ from itertools import chain
12import math
23import string
34
45from django import forms
56from django .core .paginator import EmptyPage , PageNotAnInteger , Paginator
67from django .db import models
8+ from django .db .models import Case , Q , When
79from django .dispatch import receiver
810from django .utils .functional import cached_property
11+ from django .utils .http import urlencode
912
1013from modelcluster .fields import ParentalKey , ParentalManyToManyField
1114from wagtail .admin .panels import (
@@ -75,11 +78,25 @@ def blog_posts(self):
7578 def get_context (self , request , * args , ** kwargs ):
7679 context = super ().get_context (request , * args , ** kwargs )
7780
81+ # Get blog_posts
82+ blog_posts = self .blog_posts
83+
84+ # Filter by related_service slug
85+ slug_filter = request .GET .get ("filter" )
86+ extra_url_params = {}
87+
88+ if slug_filter and slug_filter in self .taxonomy_slugs :
89+ blog_posts = blog_posts .filter (
90+ Q (related_sectors__slug = slug_filter )
91+ | Q (related_services__slug = slug_filter )
92+ )
93+ extra_url_params ["filter" ] = slug_filter
94+
7895 # use page to filter
7996 page = request .GET .get ("page" , 1 )
8097
8198 # Pagination
82- paginator = Paginator (self . blog_posts , 10 ) # Show 10 blog_posts per page
99+ paginator = Paginator (blog_posts , 10 ) # Show 10 blog_posts per page
83100
84101 try :
85102 blog_posts = paginator .page (page )
@@ -88,8 +105,20 @@ def get_context(self, request, *args, **kwargs):
88105 except EmptyPage :
89106 blog_posts = paginator .page (paginator .num_pages )
90107
108+ # Only show Sectors and Services that have been used
109+ related_sectors = Sector .objects .filter (
110+ pk__in = models .Subquery (self .blog_posts .values ("related_sectors" ))
111+ )
112+
113+ related_services = Service .objects .filter (
114+ pk__in = models .Subquery (self .blog_posts .values ("related_services" ))
115+ )
116+ tags = chain (related_services , related_sectors )
117+
91118 context .update (
92119 blog_posts = blog_posts ,
120+ tags = tags ,
121+ extra_url_params = urlencode (extra_url_params ),
93122 )
94123 return context
95124
@@ -133,6 +162,18 @@ def set_body_word_count(self):
133162 ).split ()
134163 self .body_word_count = len (body_words )
135164
165+ @cached_property
166+ def sectors (self ):
167+ return self .related_sectors .all ()
168+
169+ @cached_property
170+ def services (self ):
171+ return self .related_services .all ()
172+
173+ @property
174+ def tags (self ):
175+ return chain (self .services , self .sectors )
176+
136177 def get_related_blog_posts (self ):
137178 # Assumption that blog posts for the same division
138179 # will be under the same blog index page.
@@ -142,7 +183,7 @@ def get_related_blog_posts(self):
142183 if related := self .related_posts .values_list ("page" ):
143184 # If some blog posts have been manually selected we show those first
144185 base_queryset |= BlogPage .objects .filter (pk__in = related )
145- manual_first = models . Case (models . When (pk__in = related , then = 1 ), default = 2 )
186+ manual_first = Case (When (pk__in = related , then = 1 ), default = 2 )
146187 order_by .insert (0 , manual_first )
147188
148189 prefetch_author_images = models .Prefetch (
@@ -220,7 +261,6 @@ def type(self):
220261 FieldPanel ("related_services" , widget = forms .CheckboxSelectMultiple ),
221262 ],
222263 heading = "Taxonomies" ,
223- help_text = "For internal use only, will not be rendered on the final page." ,
224264 ),
225265 InlinePanel (
226266 "related_posts" ,
0 commit comments