Opened 96 minutes ago
#37265 assigned Bug
Admin crashes when ModelAdmin.get_action() or get_action_choices() are overridden with their pre-6.1 signatures
| Reported by: | Adam Johnson | Owned by: | Adam Johnson |
|---|---|---|---|
| Component: | contrib.admin | Version: | 6.1 |
| Severity: | Release blocker | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
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:
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 callsself.get_action(action, action_location)with two arguments and there is no deprecation shim at all for old-signatureget_action()overrides — they raiseTypeErrorimmediately, including fromModelAdminChecks._check_actions(), somanage.py checkfails too. Overrides returning the old(callable, name, description)tuple additionally break downstreamaction.name/action.funcattribute access on the newActiondataclass.- The
get_action_choices()shim (_get_action_choices_with_action_location()) exists, but always callsself.get_action_choices(request, default_choices=default_choices)withdefault_choices=None: overrides without the parameter get an unexpected keyword argument, and overrides keeping the olddefault_choices=BLANK_CHOICE_DASHdefault receive an explicitNoneinstead of their signature default (in 6.0 Django calledget_action_choices(request)with no extra arguments).
Note:
See TracTickets
for help on using tickets.