11from typing import Optional
22
3+ import django_filters
34from django .template import Context
45from django .template .defaultfilters import slugify
56from django .utils .safestring import mark_safe
6-
7- from rest_framework import filters
8-
97from froide .campaign .utils import connect_foirequest
108from froide .georegion .models import GeoRegion
11- from froide .publicbody .models import Category , Classification , PublicBody
9+ from froide .publicbody .models import Category , Classification , Jurisdiction , PublicBody
10+ from rest_framework import filters
1211
1312from ..filters import RandomOrderFilter
1413from ..models import InformationObject
@@ -78,6 +77,56 @@ def filter_queryset(self, request, queryset, provider):
7877 return queryset
7978
8079
80+ class ProviderKwargsFilter (django_filters .FilterSet ):
81+ jurisdiction = django_filters .ModelMultipleChoiceFilter (
82+ field_name = "jurisdiction_id" , queryset = Jurisdiction .objects .all ()
83+ )
84+ classification = django_filters .ModelMultipleChoiceFilter (
85+ method = "classification_filter" , queryset = Classification .objects .all ()
86+ )
87+ category = django_filters .ModelMultipleChoiceFilter (
88+ method = "category_filter" , queryset = Category .objects .all ()
89+ )
90+ region = django_filters .ModelMultipleChoiceFilter (
91+ method = "region_filter" , queryset = Category .objects .all ()
92+ )
93+ region_kind = django_filters .CharFilter (method = "region_kind_filter" )
94+
95+ class Meta :
96+ model = PublicBody
97+ fields = ["jurisdiction" , "classification" , "category" , "region" , "region_kind" ]
98+
99+ def classification_filter (self , queryset , name , value ):
100+ if not value :
101+ return queryset
102+ classifications = Classification .objects .none ().union (
103+ * [Classification .get_tree (parent = c ) for c in value ]
104+ )
105+ return queryset .filter (classification__in = classifications )
106+
107+ def category_filter (self , queryset , name , value ):
108+ if not value :
109+ return queryset
110+ categories = Category .objects .none ().union (
111+ * [Category .get_tree (parent = c ) for c in value ]
112+ )
113+ queryset = queryset .filter (categories__in = categories )
114+ return queryset
115+
116+ def region_filter (self , queryset , name , value ):
117+ if not value :
118+ return queryset
119+ ids = GeoRegion .objects .none ().union (
120+ * [GeoRegion .get_tree (parent = r ) for r in value ]
121+ )
122+ return queryset .filter (regions__in = ids )
123+
124+ def region_kind_filter (self , queryset , name , value ):
125+ if not value :
126+ return queryset
127+ return queryset .filter (regions__kind = value )
128+
129+
81130class PublicBodyProvider (BaseProvider ):
82131 IDENT_PREFIX = "pb-"
83132
@@ -91,34 +140,8 @@ class PublicBodyProvider(BaseProvider):
91140
92141 def get_queryset (self ):
93142 qs = PublicBody .objects .all ()
94- filters = {}
95- tree_filter = (
96- ("category" , "categories" , Category ),
97- ("classification" , "classification" , Classification ),
98- ("region" , "regions" , GeoRegion ),
99- )
100-
101- for key , field , model in tree_filter :
102- if key not in self .kwargs :
103- continue
104- try :
105- obj = model .objects .get (id = self .kwargs [key ])
106- except model .DoesNotExist :
107- continue
108- filters [field + "__in" ] = model .get_tree (obj )
109-
110- attr_filters = (
111- (
112- "jurisdiction" ,
113- "jurisdiction_id" ,
114- ),
115- )
116- for key , field in attr_filters :
117- if key not in self .kwargs :
118- continue
119- filters [field ] = self .kwargs [key ]
120-
121- return qs .filter (** filters )
143+ provider_filter = ProviderKwargsFilter (self .kwargs , queryset = qs )
144+ return provider_filter .qs
122145
123146 def make_ident (self , obj : PublicBody ):
124147 return "{}{}" .format (self .IDENT_PREFIX , obj .id )
0 commit comments