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