This commit is contained in:
954 2025-11-17 20:42:11 +02:00 committed by GitHub
commit 36663f0d9a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 68 additions and 1 deletions

View file

@ -6,6 +6,7 @@ Each filter subclass knows how to display a filter for a field that passes a
certain test -- e.g. being a DateField or ForeignKey.
"""
import ast
import datetime
from django.contrib.admin.exceptions import NotRegistered
@ -635,6 +636,22 @@ class AllValuesFieldListFilter(FieldListFilter):
}
class BinaryFieldListFilter(AllValuesFieldListFilter):
def __init__(self, field, request, params, model, model_admin, field_path):
super().__init__(field, request, params, model, model_admin, field_path)
self.lookup_choices = (
i.tobytes() if isinstance(i, memoryview) else i for i in self.lookup_choices
)
if self.used_parameters and self.lookup_kwarg in self.used_parameters:
self.used_parameters[self.lookup_kwarg] = (
ast.literal_eval(i) for i in self.used_parameters[self.lookup_kwarg]
)
FieldListFilter.register(
lambda f: isinstance(f, models.BinaryField), BinaryFieldListFilter
)
FieldListFilter.register(lambda f: True, AllValuesFieldListFilter)

View file

@ -99,3 +99,7 @@ class Bookmark(models.Model):
def __str__(self):
return self.url
class BookBinaryInfo(models.Model):
datas = models.BinaryField(max_length=100)

View file

@ -20,7 +20,15 @@ from django.core.exceptions import ImproperlyConfigured
from django.db import connection, models
from django.test import RequestFactory, SimpleTestCase, TestCase, override_settings
from .models import Book, Bookmark, Department, Employee, ImprovedBook, TaggedItem
from .models import (
Book,
BookBinaryInfo,
Bookmark,
Department,
Employee,
ImprovedBook,
TaggedItem,
)
def select_by(dictlist, key, value):
@ -2048,6 +2056,44 @@ class ListFiltersTests(TestCase):
queryset = changelist.get_queryset(request)
self.assertEqual(list(queryset), [jane])
def test_binaryfield_listfilter(self):
from urllib.parse import parse_qsl, quote, urlparse
class BookBinaryInfoAdmin(ModelAdmin):
list_filter = ["datas"]
datas = b"test"
BookBinaryInfo.objects.create(datas=datas)
modeladmin = BookBinaryInfoAdmin(BookBinaryInfo, site)
request = self.request_factory.get("/")
request.user = self.alfred
changelist = modeladmin.get_changelist_instance(request)
filterspec = changelist.get_filters(request)[0][0]
choices = list(filterspec.choices(changelist))
try:
choice = select_by(choices, "display", str(datas))
except IndexError as e:
raise IndexError(f"{e}, choices={choices}")
self.assertEqual(
choice["query_string"],
"?datas=%s" % (quote(str(datas)),),
)
binary_choice_href = choice["query_string"]
filter_request_query = urlparse(binary_choice_href).query
filter_request_params = dict(parse_qsl(filter_request_query))
filter_modeladmin = BookBinaryInfoAdmin(BookBinaryInfo, site)
filter_request = self.request_factory.get("/", filter_request_params)
filter_request.user = self.alfred
filter_changelist = filter_modeladmin.get_changelist_instance(filter_request)
queryset = filter_changelist.get_queryset(filter_request)
result = list(queryset)
result_datas = (
result[0].datas.tobytes()
if isinstance(result[0].datas, memoryview)
else result[0].datas
)
self.assertEqual(result_datas, datas)
class FacetsMixinTests(SimpleTestCase):
def test_get_facet_counts(self):