mirror of https://github.com/django/django.git
Refs #1873 -- Used GET.lists() in admin filters.
This commit is contained in:
parent
8d6f959be2
commit
d03dc63177
|
@ -9,6 +9,7 @@ import datetime
|
|||
|
||||
from django.contrib.admin.options import IncorrectLookupParameters
|
||||
from django.contrib.admin.utils import (
|
||||
get_last_value_from_parameters,
|
||||
get_model_from_relation,
|
||||
prepare_lookup_value,
|
||||
reverse_field_path,
|
||||
|
@ -98,7 +99,7 @@ class SimpleListFilter(FacetsMixin, ListFilter):
|
|||
)
|
||||
if self.parameter_name in params:
|
||||
value = params.pop(self.parameter_name)
|
||||
self.used_parameters[self.parameter_name] = value
|
||||
self.used_parameters[self.parameter_name] = value[-1]
|
||||
lookup_choices = self.lookups(request, model_admin)
|
||||
if lookup_choices is None:
|
||||
lookup_choices = ()
|
||||
|
@ -219,8 +220,10 @@ class RelatedFieldListFilter(FieldListFilter):
|
|||
other_model = get_model_from_relation(field)
|
||||
self.lookup_kwarg = "%s__%s__exact" % (field_path, field.target_field.name)
|
||||
self.lookup_kwarg_isnull = "%s__isnull" % field_path
|
||||
self.lookup_val = params.get(self.lookup_kwarg)
|
||||
self.lookup_val_isnull = params.get(self.lookup_kwarg_isnull)
|
||||
self.lookup_val = get_last_value_from_parameters(params, self.lookup_kwarg)
|
||||
self.lookup_val_isnull = get_last_value_from_parameters(
|
||||
params, self.lookup_kwarg_isnull
|
||||
)
|
||||
super().__init__(field, request, params, model, model_admin, field_path)
|
||||
self.lookup_choices = self.field_choices(field, request, model_admin)
|
||||
if hasattr(field, "verbose_name"):
|
||||
|
@ -317,8 +320,8 @@ class BooleanFieldListFilter(FieldListFilter):
|
|||
def __init__(self, field, request, params, model, model_admin, field_path):
|
||||
self.lookup_kwarg = "%s__exact" % field_path
|
||||
self.lookup_kwarg2 = "%s__isnull" % field_path
|
||||
self.lookup_val = params.get(self.lookup_kwarg)
|
||||
self.lookup_val2 = params.get(self.lookup_kwarg2)
|
||||
self.lookup_val = get_last_value_from_parameters(params, self.lookup_kwarg)
|
||||
self.lookup_val2 = get_last_value_from_parameters(params, self.lookup_kwarg2)
|
||||
super().__init__(field, request, params, model, model_admin, field_path)
|
||||
if (
|
||||
self.used_parameters
|
||||
|
@ -388,8 +391,10 @@ class ChoicesFieldListFilter(FieldListFilter):
|
|||
def __init__(self, field, request, params, model, model_admin, field_path):
|
||||
self.lookup_kwarg = "%s__exact" % field_path
|
||||
self.lookup_kwarg_isnull = "%s__isnull" % field_path
|
||||
self.lookup_val = params.get(self.lookup_kwarg)
|
||||
self.lookup_val_isnull = params.get(self.lookup_kwarg_isnull)
|
||||
self.lookup_val = get_last_value_from_parameters(params, self.lookup_kwarg)
|
||||
self.lookup_val_isnull = get_last_value_from_parameters(
|
||||
params, self.lookup_kwarg_isnull
|
||||
)
|
||||
super().__init__(field, request, params, model, model_admin, field_path)
|
||||
|
||||
def expected_parameters(self):
|
||||
|
@ -450,7 +455,7 @@ class DateFieldListFilter(FieldListFilter):
|
|||
def __init__(self, field, request, params, model, model_admin, field_path):
|
||||
self.field_generic = "%s__" % field_path
|
||||
self.date_params = {
|
||||
k: v for k, v in params.items() if k.startswith(self.field_generic)
|
||||
k: v[-1] for k, v in params.items() if k.startswith(self.field_generic)
|
||||
}
|
||||
|
||||
now = timezone.now()
|
||||
|
@ -550,8 +555,10 @@ class AllValuesFieldListFilter(FieldListFilter):
|
|||
def __init__(self, field, request, params, model, model_admin, field_path):
|
||||
self.lookup_kwarg = field_path
|
||||
self.lookup_kwarg_isnull = "%s__isnull" % field_path
|
||||
self.lookup_val = params.get(self.lookup_kwarg)
|
||||
self.lookup_val_isnull = params.get(self.lookup_kwarg_isnull)
|
||||
self.lookup_val = get_last_value_from_parameters(params, self.lookup_kwarg)
|
||||
self.lookup_val_isnull = get_last_value_from_parameters(
|
||||
params, self.lookup_kwarg_isnull
|
||||
)
|
||||
self.empty_value_display = model_admin.get_empty_value_display()
|
||||
parent_model, reverse_path = reverse_field_path(model, field_path)
|
||||
# Obey parent ModelAdmin queryset when deciding which options to show
|
||||
|
@ -646,7 +653,7 @@ class EmptyFieldListFilter(FieldListFilter):
|
|||
)
|
||||
)
|
||||
self.lookup_kwarg = "%s__isempty" % field_path
|
||||
self.lookup_val = params.get(self.lookup_kwarg)
|
||||
self.lookup_val = get_last_value_from_parameters(params, self.lookup_kwarg)
|
||||
super().__init__(field, request, params, model, model_admin, field_path)
|
||||
|
||||
def get_lookup_condition(self):
|
||||
|
|
|
@ -54,10 +54,17 @@ def lookup_spawns_duplicates(opts, lookup_path):
|
|||
return False
|
||||
|
||||
|
||||
def get_last_value_from_parameters(parameters, key):
|
||||
value = parameters.get(key)
|
||||
return value[-1] if isinstance(value, list) else value
|
||||
|
||||
|
||||
def prepare_lookup_value(key, value, separator=","):
|
||||
"""
|
||||
Return a lookup value prepared to be used in queryset filtering.
|
||||
"""
|
||||
if isinstance(value, list):
|
||||
value = value[-1]
|
||||
# if key ends with __in, split parameter into separate values
|
||||
if key.endswith("__in"):
|
||||
value = value.split(separator)
|
||||
|
|
|
@ -123,10 +123,13 @@ class ChangeList:
|
|||
)
|
||||
self.to_field = to_field
|
||||
self.params = dict(request.GET.items())
|
||||
self.filter_params = dict(request.GET.lists())
|
||||
if PAGE_VAR in self.params:
|
||||
del self.params[PAGE_VAR]
|
||||
del self.filter_params[PAGE_VAR]
|
||||
if ERROR_FLAG in self.params:
|
||||
del self.params[ERROR_FLAG]
|
||||
del self.filter_params[ERROR_FLAG]
|
||||
self.remove_facet_link = self.get_query_string(remove=[IS_FACETS_VAR])
|
||||
self.add_facet_link = self.get_query_string({IS_FACETS_VAR: True})
|
||||
|
||||
|
@ -156,7 +159,7 @@ class ChangeList:
|
|||
"""
|
||||
Return all params except IGNORED_PARAMS.
|
||||
"""
|
||||
params = params or self.params
|
||||
params = params or self.filter_params
|
||||
lookup_params = params.copy() # a dictionary of the query string
|
||||
# Remove all the parameters that are globally and systematically
|
||||
# ignored.
|
||||
|
@ -171,7 +174,7 @@ class ChangeList:
|
|||
has_active_filters = False
|
||||
|
||||
for key, value in lookup_params.items():
|
||||
if not self.model_admin.lookup_allowed(key, value):
|
||||
if not self.model_admin.lookup_allowed(key, value[-1]):
|
||||
raise DisallowedModelAdminLookup("Filtering by %s not allowed" % key)
|
||||
|
||||
filter_specs = []
|
||||
|
@ -224,9 +227,9 @@ class ChangeList:
|
|||
day = lookup_params.pop("%s__day" % self.date_hierarchy, None)
|
||||
try:
|
||||
from_date = datetime(
|
||||
int(year),
|
||||
int(month if month is not None else 1),
|
||||
int(day if day is not None else 1),
|
||||
int(year[-1]),
|
||||
int(month[-1] if month is not None else 1),
|
||||
int(day[-1] if day is not None else 1),
|
||||
)
|
||||
except ValueError as e:
|
||||
raise IncorrectLookupParameters(e) from e
|
||||
|
@ -273,7 +276,7 @@ class ChangeList:
|
|||
new_params = {}
|
||||
if remove is None:
|
||||
remove = []
|
||||
p = self.params.copy()
|
||||
p = self.filter_params.copy()
|
||||
for r in remove:
|
||||
for k in list(p):
|
||||
if k.startswith(r):
|
||||
|
@ -284,7 +287,7 @@ class ChangeList:
|
|||
del p[k]
|
||||
else:
|
||||
p[k] = v
|
||||
return "?%s" % urlencode(sorted(p.items()))
|
||||
return "?%s" % urlencode(sorted(p.items()), doseq=True)
|
||||
|
||||
def get_results(self, request):
|
||||
paginator = self.model_admin.get_paginator(
|
||||
|
|
Loading…
Reference in New Issue