1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 | from django.contrib.admin.filterspecs import FilterSpec
from django.contrib.admin.filterspecs import RelatedFilterSpec
class FKFilterSpec(RelatedFilterSpec):
def __init__(self, f, request, params, model, model_admin):
filter_by_key = f.name+'_fk_filter_by'
filter_by_val = getattr(model_admin, filter_by_key, None)
if filter_by_val != None:
self.fk_filter_on = True
# we call FilterSpec constructor, not RelatedFilterSpec
# constructor; RelatedFilterSpec constructor will try to
# get all the pk values on the related models, which we
# won't need.
FilterSpec.__init__(self, f, request, params, model, model_admin)
filter_name_key = f.name+'_fk_filter_name'
filter_name_val = getattr(model_admin, filter_name_key, None)
if filter_name_val == None:
self.lookup_title = f.verbose_name
else:
self.lookup_title = f.verbose_name+' '+filter_name_val
self.lookup_kwarg = f.name+'__'+filter_by_val+'__exact'
self.lookup_val = request.GET.get(self.lookup_kwarg, None)
values_list = f.rel.to.objects.values_list(filter_by_val, flat=True).distinct()
self.lookup_choices = list(values_list)
else:
RelatedFilterSpec.__init__(self, f, request, params, model, model_admin)
self.fk_filter_on = False
filter_related_key = f.name+'_fk_filter_related_only'
filter_related_val = getattr(model_admin, filter_related_key, False)
filter_nf_key = f.name+'_fk_filter_name_field'
filter_nf_val = getattr(model_admin, filter_nf_key, 'pk')
if filter_related_val:
values_list = model_admin.queryset(request).distinct().values_list(f.name+'__pk',f.name+'__'+filter_nf_val).order_by(f.name+'__'+filter_nf_val).distinct()
self.lookup_choices = list(values_list)
def choices(self, cl):
yield {'selected': self.lookup_val is None,
'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
'display': _('All')}
if self.fk_filter_on:
for val in self.lookup_choices:
yield {'selected': smart_unicode(val) == self.lookup_val,
'query_string': cl.get_query_string({self.lookup_kwarg: val}),
'display': val}
else:
for pk_val,val in self.lookup_choices:
yield {'selected': self.lookup_val == smart_unicode(pk_val),
'query_string': cl.get_query_string({self.lookup_kwarg: pk_val}),
'display': val}
FilterSpec.filter_specs.insert(0, (lambda f: bool(f.rel), FKFilterSpec))
|
Comments
I merged the changes described here into 2260.
#