summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorsarahboyce <sarahvboyce95@gmail.com>2023-03-06 14:59:20 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-03-16 08:34:26 +0100
commitd03dc63177ad3ba6e685e314eed45d6a8ec5cb0c (patch)
tree31eb7c9a9c0c2f3bc8f82349ccb3b883448d90c3 /django
parent8d6f959be226edd9c0eb054a9babe9d4af399717 (diff)
downloaddjango-d03dc63177ad3ba6e685e314eed45d6a8ec5cb0c.tar.gz
Refs #1873 -- Used GET.lists() in admin filters.
Diffstat (limited to 'django')
-rw-r--r--django/contrib/admin/filters.py29
-rw-r--r--django/contrib/admin/utils.py7
-rw-r--r--django/contrib/admin/views/main.py17
3 files changed, 35 insertions, 18 deletions
diff --git a/django/contrib/admin/filters.py b/django/contrib/admin/filters.py
index 9e468dedd9..3ae7805dc2 100644
--- a/django/contrib/admin/filters.py
+++ b/django/contrib/admin/filters.py
@@ -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):
diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py
index b971bd528f..90442788c9 100644
--- a/django/contrib/admin/utils.py
+++ b/django/contrib/admin/utils.py
@@ -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)
diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py
index 6d88dfc883..c0c03819f3 100644
--- a/django/contrib/admin/views/main.py
+++ b/django/contrib/admin/views/main.py
@@ -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(