1
0
mirror of https://github.com/django/django.git synced 2025-10-31 09:41:08 +00:00

Fixed #26001 -- Fixed non-string field exact lookups in ModelAdmin.search_fields.

This commit is contained in:
0saurabh0
2024-11-01 08:26:10 +01:00
committed by Sarah Boyce
parent cd4497254e
commit f223729f8f
3 changed files with 48 additions and 3 deletions

View File

@@ -41,6 +41,7 @@ from django.core.exceptions import (
from django.core.paginator import Paginator
from django.db import models, router, transaction
from django.db.models.constants import LOOKUP_SEP
from django.db.models.functions import Cast
from django.forms.formsets import DELETION_FIELD_NAME, all_valid
from django.forms.models import (
BaseInlineFormSet,
@@ -1207,9 +1208,33 @@ class ModelAdmin(BaseModelAdmin):
may_have_duplicates = False
search_fields = self.get_search_fields(request)
if search_fields and search_term:
orm_lookups = [
construct_search(str(search_field)) for search_field in search_fields
]
str_annotations = {}
orm_lookups = []
for field in search_fields:
if field.endswith("__exact"):
field_name = field.rsplit("__exact", 1)[0]
try:
field_obj = queryset.model._meta.get_field(field_name)
except FieldDoesNotExist:
lookup = construct_search(field)
orm_lookups.append(lookup)
continue
# Add string cast annotations for non-string exact lookups.
if not isinstance(field_obj, (models.CharField, models.TextField)):
str_annotations[f"{field_name}_str"] = Cast(
field_name, output_field=models.CharField()
)
orm_lookups.append(f"{field_name}_str__exact")
else:
lookup = construct_search(field)
orm_lookups.append(lookup)
else:
lookup = construct_search(str(field))
orm_lookups.append(lookup)
if str_annotations:
queryset = queryset.annotate(**str_annotations)
term_queries = []
for bit in smart_split(search_term):
if bit.startswith(('"', "'")) and bit[0] == bit[-1]: