#37265: Admin crashes when ModelAdmin.get_action() or get_action_choices() are
overridden with their pre-6.1 signatures
-------------------------------------------+------------------------------
Reporter: Adam Johnson | Owner: Adam Johnson
Type: Bug | Status: assigned
Component: contrib.admin | Version: 6.1
Severity: Release blocker | Keywords:
Triage Stage: Unreviewed | Has patch: 1
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------------+------------------------------
Django 6.1 crashes with a 500 on every admin page that uses actions (and
even during ''system checks'') for projects that override
`ModelAdmin.get_action()` or `ModelAdmin.get_action_choices()` with their
documented pre-6.1 signatures.
Here’s a minimal reproduction that works on Django 6.0, but crashes on 6.1
and main:
{{{#!python
from django.contrib import admin
from django.db.models import BLANK_CHOICE_DASH
@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
actions = ["my_action"]
# (1) TypeError: get_action() takes 2 positional arguments but 3 were
given
# Raised by system checks and by any changelist/change form
request.
def get_action(self, action):
return super().get_action(action)
# (2) TypeError: get_action_choices() got an unexpected keyword
argument 'default_choices'
def get_action_choices(self, request):
return super().get_action_choices(request)
# (2b) Or, with the old default: TypeError: 'NoneType' object is not
iterable
# def get_action_choices(self, request,
default_choices=BLANK_CHOICE_DASH):
# return [*default_choices, ...]
@admin.action(description="My action")
def my_action(self, request, queryset):
...
}}}
Regression in f30acb184f75fd9260cfd6ddc48a3bbbd49f9c1d (Fixed #12090 --
Added admin actions to the admin change form), interacting with 63c56cda1
(blank-choice default changed to `None`):
* `ModelAdmin._get_base_actions()` now calls `self.get_action(action,
action_location)` with two arguments and there is '''no deprecation shim
at all''' for old-signature `get_action()` overrides — they raise
`TypeError` immediately, including from
`ModelAdminChecks._check_actions()`, so `manage.py check` fails too.
Overrides returning the old `(callable, name, description)` tuple
additionally break downstream `
action.name`/`action.func` attribute access
on the new `Action` dataclass.
* The `get_action_choices()` shim
(`_get_action_choices_with_action_location()`) exists, but always calls
`self.get_action_choices(request, default_choices=default_choices)` with
`default_choices=None`: overrides without the parameter get an unexpected
keyword argument, and overrides keeping the old
`default_choices=BLANK_CHOICE_DASH` default receive an explicit `None`
instead of their signature default (in 6.0 Django called
`get_action_choices(request)` with no extra arguments).
--
Ticket URL: <
https://code.djangoproject.com/ticket/37265>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.