Code

Ticket #8528: ticket8528-1.2.diff

File ticket8528-1.2.diff, 3.4 KB (added by arnaudr, 4 years ago)

Patches cleanly against 1.2

Line 
1Index: django/contrib/admin/filterspecs.py
2===================================================================
3--- django/contrib/admin/filterspecs.py (revision 13293)
4+++ django/contrib/admin/filterspecs.py (working copy)
5@@ -60,7 +60,9 @@
6             self.lookup_title = f.verbose_name
7         rel_name = f.rel.get_related_field().name
8         self.lookup_kwarg = '%s__%s__exact' % (f.name, rel_name)
9+        self.lookup_null_kwarg = '%s__isnull' % (f.name)
10         self.lookup_val = request.GET.get(self.lookup_kwarg, None)
11+        self.lookup_null = request.GET.get(self.lookup_null_kwarg, None)
12         self.lookup_choices = f.get_choices(include_blank=False)
13 
14     def has_output(self):
15@@ -70,13 +72,17 @@
16         return self.lookup_title
17 
18     def choices(self, cl):
19-        yield {'selected': self.lookup_val is None,
20-               'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
21+        yield {'selected': self.lookup_val is None and not self.lookup_null,
22+               'query_string': cl.get_query_string({}, [self.lookup_kwarg, self.lookup_null_kwarg]),
23                'display': _('All')}
24         for pk_val, val in self.lookup_choices:
25             yield {'selected': self.lookup_val == smart_unicode(pk_val),
26-                   'query_string': cl.get_query_string({self.lookup_kwarg: pk_val}),
27+                   'query_string': cl.get_query_string({self.lookup_kwarg: pk_val}, [self.lookup_null_kwarg]),
28                    'display': val}
29+        if self.field.null:
30+            yield {'selected': self.lookup_null,
31+                   'query_string': cl.get_query_string({self.lookup_null_kwarg: 'True'}, [self.lookup_kwarg]),
32+                   'display': _("None")}
33 
34 FilterSpec.register(lambda f: bool(f.rel), RelatedFilterSpec)
35 
36@@ -162,18 +168,24 @@
37     def __init__(self, f, request, params, model, model_admin):
38         super(AllValuesFilterSpec, self).__init__(f, request, params, model, model_admin)
39         self.lookup_val = request.GET.get(f.name, None)
40+        self.lookup_null = request.GET.get(f.name + '__isnull', None)
41         self.lookup_choices = model_admin.queryset(request).distinct().order_by(f.name).values(f.name)
42 
43     def title(self):
44         return self.field.verbose_name
45 
46     def choices(self, cl):
47-        yield {'selected': self.lookup_val is None,
48-               'query_string': cl.get_query_string({}, [self.field.name]),
49+        yield {'selected': self.lookup_val is None and not self.lookup_null,
50+               'query_string': cl.get_query_string({}, [self.field.name, self.field.name + '__isnull']),
51                'display': _('All')}
52         for val in self.lookup_choices:
53-            val = smart_unicode(val[self.field.name])
54-            yield {'selected': self.lookup_val == val,
55-                   'query_string': cl.get_query_string({self.field.name: val}),
56-                   'display': val}
57+            if val[self.field.name] is None:
58+                yield {'selected': self.lookup_null,
59+                       'query_string': cl.get_query_string({self.field.name + '__isnull': 'True'}, [self.field.name]),
60+                       'display': _("None")}
61+            else:
62+                val = smart_unicode(val[self.field.name])
63+                yield {'selected': self.lookup_val == val,
64+                       'query_string': cl.get_query_string({self.field.name: val}),
65+                       'display': val}
66 FilterSpec.register(lambda f: True, AllValuesFilterSpec)