diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 0b79ac75ef..33c86d2ba9 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -17,7 +17,7 @@ from django.contrib.admin.exceptions import DisallowedModelAdminToField from django.contrib.admin.templatetags.admin_urls import add_preserved_filters from django.contrib.admin.utils import ( NestedObjects, construct_change_message, flatten_fieldsets, - get_deleted_objects, lookup_needs_distinct, model_format_dict, + get_deleted_objects, lookup_spawns_duplicates, model_format_dict, model_ngettext, quote, unquote, ) from django.contrib.admin.widgets import ( @@ -1031,7 +1031,7 @@ class ModelAdmin(BaseModelAdmin): for orm_lookup in orm_lookups] queryset = queryset.filter(reduce(operator.or_, or_queries)) may_have_duplicates |= any( - lookup_needs_distinct(self.opts, search_spec) + lookup_spawns_duplicates(self.opts, search_spec) for search_spec in orm_lookups ) return queryset, may_have_duplicates diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py index ba06da5211..7eea70b194 100644 --- a/django/contrib/admin/utils.py +++ b/django/contrib/admin/utils.py @@ -25,9 +25,9 @@ class FieldIsAForeignKeyColumnName(Exception): pass -def lookup_needs_distinct(opts, lookup_path): +def lookup_spawns_duplicates(opts, lookup_path): """ - Return True if 'distinct()' should be used to query the given lookup path. + Return True if the given lookup path spawns duplicates. """ lookup_fields = lookup_path.split(LOOKUP_SEP) # Go through the fields (following all relations) and look for an m2m. @@ -45,7 +45,8 @@ def lookup_needs_distinct(opts, lookup_path): path_info = field.get_path_info() opts = path_info[-1].to_opts if any(path.m2m for path in path_info): - # This field is a m2m relation so distinct must be called. + # This field is a m2m relation so duplicates must be + # handled. return True return False diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index a54ef25f23..2e3e758164 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -11,7 +11,8 @@ from django.contrib.admin.options import ( IS_POPUP_VAR, TO_FIELD_VAR, IncorrectLookupParameters, ) from django.contrib.admin.utils import ( - get_fields_from_path, lookup_needs_distinct, prepare_lookup_value, quote, + get_fields_from_path, lookup_spawns_duplicates, prepare_lookup_value, + quote, ) from django.core.exceptions import ( FieldDoesNotExist, ImproperlyConfigured, SuspiciousOperation, @@ -154,10 +155,12 @@ class ChangeList: self.model, self.model_admin, field_path=field_path, ) # field_list_filter_class removes any lookup_params it - # processes. If that happened, check if distinct() is needed to - # remove duplicate results. + # processes. If that happened, check if duplicates should be + # removed. if lookup_params_count > len(lookup_params): - may_have_duplicates |= lookup_needs_distinct(self.lookup_opts, field_path) + may_have_duplicates |= lookup_spawns_duplicates( + self.lookup_opts, field_path, + ) if spec and spec.has_output(): filter_specs.append(spec) if lookup_params_count > len(lookup_params): @@ -198,12 +201,12 @@ class ChangeList: # have been removed from lookup_params, which now only contains other # parameters passed via the query string. We now loop through the # remaining parameters both to ensure that all the parameters are valid - # fields and to determine if at least one of them needs distinct(). If + # fields and to determine if at least one of them spawns duplicates. If # the lookup parameters aren't real fields, then bail out. try: for key, value in lookup_params.items(): lookup_params[key] = prepare_lookup_value(key, value) - may_have_duplicates |= lookup_needs_distinct(self.lookup_opts, key) + may_have_duplicates |= lookup_spawns_duplicates(self.lookup_opts, key) return ( filter_specs, bool(filter_specs), lookup_params, may_have_duplicates, has_active_filters, diff --git a/docs/releases/4.0.txt b/docs/releases/4.0.txt index ab65c31094..e7eab6fa43 100644 --- a/docs/releases/4.0.txt +++ b/docs/releases/4.0.txt @@ -396,6 +396,9 @@ Miscellaneous As a side-effect ``makemigrations`` might generate no-op ``AlterField`` operations for ``ForeignKey`` fields in some cases. +* The undocumented ``django.contrib.admin.utils.lookup_needs_distinct()`` + function is renamed to ``lookup_spawns_duplicates()``. + .. _deprecated-features-4.0: Features deprecated in 4.0