#32682 closed Bug (fixed)
Deleting objects after searching related many to many field crashes the admin page
Reported by: | Zain Patel | Owned by: | Mariusz Felisiak |
---|---|---|---|
Component: | contrib.admin | Version: | 3.2 |
Severity: | Release blocker | Keywords: | regression, admin, delete |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Minimal reproduction:
# models.py class Post(models.Model): title = models.String(...) authors = models.ManyToMany("User", ...) class User(models.Model): email = models.String(...) # admin.py class PostAdmin(admin.ModelAdmin): search_fields = ("title", "authors__email")
then opening the admin site, opening the post page that contains only one post (any title and author assigned) and entering a search term (e.g the first 2 characters of the title), selecting the post and then using the delete action results in an Internal Sever Error 500 with an error/stack-trace:
Internal Server Error: /admin/post/post/ Traceback (most recent call last): File "...lib/python3.7/site-packages/django/core/handlers/exception.py", line 47, in inner response = get_response(request) File "...lib/python3.7/site-packages/django/core/handlers/base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "...lib/python3.7/site-packages/django/contrib/admin/options.py", line 616, in wrapper return self.admin_site.admin_view(view)(*args, **kwargs) File "...lib/python3.7/site-packages/django/utils/decorators.py", line 130, in _wrapped_view response = view_func(request, *args, **kwargs) File "...lib/python3.7/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func response = view_func(request, *args, **kwargs) File "...lib/python3.7/site-packages/django/contrib/admin/sites.py", line 241, in inner return view(request, *args, **kwargs) File "...lib/python3.7/site-packages/django/utils/decorators.py", line 43, in _wrapper return bound_method(*args, **kwargs) File "...lib/python3.7/site-packages/django/utils/decorators.py", line 130, in _wrapped_view response = view_func(request, *args, **kwargs) File "...lib/python3.7/site-packages/django/contrib/admin/options.py", line 1737, in changelist_view response = self.response_action(request, queryset=cl.get_queryset(request)) File "...lib/python3.7/site-packages/django/contrib/admin/options.py", line 1406, in response_action response = func(self, request, queryset) File "...lib/python3.7/site-packages/django/contrib/admin/actions.py", line 45, in delete_selected modeladmin.delete_queryset(request, queryset) File "...lib/python3.7/site-packages/django/contrib/admin/options.py", line 1107, in delete_queryset queryset.delete() File "...lib/python3.7/site-packages/django/db/models/query.py", line 728, in delete raise TypeError('Cannot call delete() after .distinct().') TypeError: Cannot call delete() after .distinct(). "POST /admin/post/post/?q=my HTTP/1.1" 500 137654
I can confirm that pip install django==3.1.8
fixes the error, and after having a look at the diff between stable/3.2.x and 3.1.8, I suspect the "regression" comes about from the work done on preserving the filters on delete or something along those lines - I haven't done a thorough investigation yet. Presumably .distinct()
is being called because of the search involving the many to many field.
I am using a Postgres database.
Change History (11)
comment:1 by , 4 years ago
Owner: | changed from | to
---|---|
Severity: | Normal → Release blocker |
Status: | new → assigned |
Triage Stage: | Unreviewed → Accepted |
This exception was introduce in 6307c3f1a123f5975c73b231e8ac4f115fd72c0d and revealed a possible data loss issue in the admin. IMO we should use
Exists()
instead ofdistinct()
, e.g.