Refs #32682 -- Renamed use_distinct variable to may_have_duplicates.
QuerySet.distinct() is not the only way to avoid duplicate, it's also not preferred.
This commit is contained in:
parent
4074f38e1d
commit
cd74aad90e
|
@ -1019,7 +1019,7 @@ class ModelAdmin(BaseModelAdmin):
|
|||
# Otherwise, use the field with icontains.
|
||||
return "%s__icontains" % field_name
|
||||
|
||||
use_distinct = False
|
||||
may_have_duplicates = False
|
||||
search_fields = self.get_search_fields(request)
|
||||
if search_fields and search_term:
|
||||
orm_lookups = [construct_search(str(search_field))
|
||||
|
@ -1030,9 +1030,11 @@ class ModelAdmin(BaseModelAdmin):
|
|||
or_queries = [models.Q(**{orm_lookup: bit})
|
||||
for orm_lookup in orm_lookups]
|
||||
queryset = queryset.filter(reduce(operator.or_, or_queries))
|
||||
use_distinct |= any(lookup_needs_distinct(self.opts, search_spec) for search_spec in orm_lookups)
|
||||
|
||||
return queryset, use_distinct
|
||||
may_have_duplicates |= any(
|
||||
lookup_needs_distinct(self.opts, search_spec)
|
||||
for search_spec in orm_lookups
|
||||
)
|
||||
return queryset, may_have_duplicates
|
||||
|
||||
def get_preserved_filters(self, request):
|
||||
"""
|
||||
|
|
|
@ -122,7 +122,7 @@ class ChangeList:
|
|||
|
||||
def get_filters(self, request):
|
||||
lookup_params = self.get_filters_params()
|
||||
use_distinct = False
|
||||
may_have_duplicates = False
|
||||
has_active_filters = False
|
||||
|
||||
for key, value in lookup_params.items():
|
||||
|
@ -157,7 +157,7 @@ class ChangeList:
|
|||
# processes. If that happened, check if distinct() is needed to
|
||||
# remove duplicate results.
|
||||
if lookup_params_count > len(lookup_params):
|
||||
use_distinct = use_distinct or lookup_needs_distinct(self.lookup_opts, field_path)
|
||||
may_have_duplicates |= lookup_needs_distinct(self.lookup_opts, field_path)
|
||||
if spec and spec.has_output():
|
||||
filter_specs.append(spec)
|
||||
if lookup_params_count > len(lookup_params):
|
||||
|
@ -203,9 +203,9 @@ class ChangeList:
|
|||
try:
|
||||
for key, value in lookup_params.items():
|
||||
lookup_params[key] = prepare_lookup_value(key, value)
|
||||
use_distinct = use_distinct or lookup_needs_distinct(self.lookup_opts, key)
|
||||
may_have_duplicates |= lookup_needs_distinct(self.lookup_opts, key)
|
||||
return (
|
||||
filter_specs, bool(filter_specs), lookup_params, use_distinct,
|
||||
filter_specs, bool(filter_specs), lookup_params, may_have_duplicates,
|
||||
has_active_filters,
|
||||
)
|
||||
except FieldDoesNotExist as e:
|
||||
|
@ -445,7 +445,7 @@ class ChangeList:
|
|||
self.filter_specs,
|
||||
self.has_filters,
|
||||
remaining_lookup_params,
|
||||
filters_use_distinct,
|
||||
filters_may_have_duplicates,
|
||||
self.has_active_filters,
|
||||
) = self.get_filters(request)
|
||||
# Then, we let every list filter modify the queryset to its liking.
|
||||
|
@ -480,7 +480,9 @@ class ChangeList:
|
|||
qs = qs.order_by(*ordering)
|
||||
|
||||
# Apply search results
|
||||
qs, search_use_distinct = self.model_admin.get_search_results(request, qs, self.query)
|
||||
qs, search_may_have_duplicates = self.model_admin.get_search_results(
|
||||
request, qs, self.query,
|
||||
)
|
||||
|
||||
# Set query string for clearing all filters.
|
||||
self.clear_all_filters_qs = self.get_query_string(
|
||||
|
@ -488,7 +490,7 @@ class ChangeList:
|
|||
remove=self.get_filters_params(),
|
||||
)
|
||||
# Remove duplicates from results, if necessary
|
||||
if filters_use_distinct | search_use_distinct:
|
||||
if filters_may_have_duplicates | search_may_have_duplicates:
|
||||
return qs.distinct()
|
||||
else:
|
||||
return qs
|
||||
|
|
|
@ -1576,14 +1576,16 @@ templates used by the :class:`ModelAdmin` views:
|
|||
search_fields = ('name',)
|
||||
|
||||
def get_search_results(self, request, queryset, search_term):
|
||||
queryset, use_distinct = super().get_search_results(request, queryset, search_term)
|
||||
queryset, may_have_duplicates = super().get_search_results(
|
||||
request, queryset, search_term,
|
||||
)
|
||||
try:
|
||||
search_term_as_int = int(search_term)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
queryset |= self.model.objects.filter(age=search_term_as_int)
|
||||
return queryset, use_distinct
|
||||
return queryset, may_have_duplicates
|
||||
|
||||
This implementation is more efficient than ``search_fields =
|
||||
('name', '=age')`` which results in a string comparison for the numeric
|
||||
|
|
|
@ -653,14 +653,16 @@ class PluggableSearchPersonAdmin(admin.ModelAdmin):
|
|||
search_fields = ('name',)
|
||||
|
||||
def get_search_results(self, request, queryset, search_term):
|
||||
queryset, use_distinct = super().get_search_results(request, queryset, search_term)
|
||||
queryset, may_have_duplicates = super().get_search_results(
|
||||
request, queryset, search_term,
|
||||
)
|
||||
try:
|
||||
search_term_as_int = int(search_term)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
queryset |= self.model.objects.filter(age=search_term_as_int)
|
||||
return queryset, use_distinct
|
||||
return queryset, may_have_duplicates
|
||||
|
||||
|
||||
class AlbumAdmin(admin.ModelAdmin):
|
||||
|
|
Loading…
Reference in New Issue