[Django] #36921: KeyError when adding new objects two relations deep via inlines but the intermediate model is not registered with the admin

0 views
Skip to first unread message

Django

unread,
Feb 11, 2026, 2:56:46 PM (12 hours ago) Feb 11
to django-...@googlegroups.com
#36921: KeyError when adding new objects two relations deep via inlines but the
intermediate model is not registered with the admin
-----------------------------+-------------------------------------------
Reporter: Jacob Walls | Type: Bug
Status: new | Component: contrib.admin
Version: dev | Severity: Release blocker
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+-------------------------------------------
With these models:
{{{#!py
class Analysis(models.Model): ...

class Song(models.Model):
users = models.ManyToManyField("auth.User")
analysis = models.ForeignKey("Analysis", on_delete=models.CASCADE,
null=True)
}}}
And these admins:
{{{#!py
class SongInline(admin.TabularInline):
model = Song


class AnalysisAdmin(admin.ModelAdmin):
inlines = [SongInline]

admin.site.register([Analysis], AnalysisAdmin)
}}}

1. Admin: Analysis: Add
2. Click the "+" in the Users column of the Songs inline
3. Fill out the field
4. Notice `Song` is in the URL as the `source_model` arg. This will be a
problem, since `Song` is not registered with the admin.
5. Submit

{{{#!py

File "/Users/jacobwalls/django/django/contrib/admin/options.py", line
711, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/utils/decorators.py", line 191, in
_view_wrapper
result = _process_exception(request, e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/utils/decorators.py", line 189, in
_view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/views/decorators/cache.py", line
79, in _view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/contrib/admin/sites.py", line 247,
in inner
return view(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/utils/decorators.py", line 47, in
_wrapper
return bound_method(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/views/decorators/debug.py", line
142, in sensitive_post_parameters_wrapper
return view(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/utils/decorators.py", line 191, in
_view_wrapper
result = _process_exception(request, e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/utils/decorators.py", line 189, in
_view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/contrib/auth/admin.py", line 119,
in add_view
return self._add_view(request, form_url, extra_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/contrib/auth/admin.py", line 147,
in _add_view
return super().add_view(request, form_url, extra_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/contrib/admin/options.py", line
1984, in add_view
return self.changeform_view(request, None, form_url, extra_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/utils/decorators.py", line 47, in
_wrapper
return bound_method(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/utils/decorators.py", line 191, in
_view_wrapper
result = _process_exception(request, e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/utils/decorators.py", line 189, in
_view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/contrib/admin/options.py", line
1842, in changeform_view
return self._changeform_view(request, object_id, form_url,
extra_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/contrib/admin/options.py", line
1900, in _changeform_view
return self.response_add(request, new_object)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/contrib/auth/admin.py", line 251,
in response_add
return super().response_add(request, obj, post_url_continue)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jacobwalls/django/django/contrib/admin/options.py", line
1431, in response_add
source_admin = self.admin_site._registry[source_model]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Exception Type: KeyError at /admin/auth/user/add/
Exception Value: <class 'earTrain.models.Song'>
}}}

Regression in b1ffa9a9d78b0c2c5ad6ed5a1d84e380d5cfd010.
--
Ticket URL: <https://code.djangoproject.com/ticket/36921>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Feb 11, 2026, 4:13:51 PM (11 hours ago) Feb 11
to django-...@googlegroups.com
#36921: KeyError when adding new objects two relations deep via inlines but the
intermediate model is not registered with the admin
---------------------------------+--------------------------------------
Reporter: Jacob Walls | Owner: (none)
Type: Bug | Status: new
Component: contrib.admin | Version: dev
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
---------------------------------+--------------------------------------
Comment (by Sean Helvey):

Eek! I'm not familiar with the triage process but believe this patch would
add an if statement to check for that. It worked for me locally:


{{{
- source_admin =
self.admin_site._registry[source_model]
- form = source_admin.get_form(request)()
- if self.opts.verbose_name_plural in form.fields:
- field =
form.fields[self.opts.verbose_name_plural]
- for option_value, option_label in field.choices:
- # Check if this is an optgroup (label is a
sequence
- # of choices rather than a single string
value).
- if isinstance(option_label, (list, tuple)):
- # It's an optgroup:
- # (group_name, [(value, label), ...])
- optgroup_label = option_value
- for choice_value, choice_display in
option_label:
- if choice_display == str(obj):
- popup_response["optgroup"] =
str(optgroup_label)
- break
+ if source_model in self.admin_site._registry:
+ source_admin =
self.admin_site._registry[source_model]
+ form = source_admin.get_form(request)()
+ if self.opts.verbose_name_plural in form.fields:
+ field =
form.fields[self.opts.verbose_name_plural]
+ for option_value, option_label in
field.choices:
+ # Check if this is an optgroup (label is
a
+ # sequence of choices rather than a
single
+ # string value).
+ if isinstance(option_label, (list,
tuple)):
+ # It's an optgroup:
+ # (group_name, [(value, label), ...])
+ optgroup_label = option_value
+ for choice_value, choice_display in
option_label:
+ if choice_display == str(obj):
+ popup_response["optgroup"] =
str(
+ optgroup_label
+ )
+ break
}}}

How can I help?
--
Ticket URL: <https://code.djangoproject.com/ticket/36921#comment:1>

Django

unread,
Feb 11, 2026, 4:24:19 PM (11 hours ago) Feb 11
to django-...@googlegroups.com
#36921: KeyError when adding new objects two relations deep via inlines but the
intermediate model is not registered with the admin
---------------------------------+--------------------------------------
Reporter: Jacob Walls | Owner: (none)
Type: Bug | Status: new
Component: contrib.admin | Version: dev
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
---------------------------------+--------------------------------------
Comment (by Natalia Bidart):

Replying to [comment:1 Sean Helvey]:
> How can I help?

If you have reproduced the reported issue, you can accept the ticket
saying so. If you also want to work on the ticket, assign it to yourself
after accepting. More details on the triage process here:
https://docs.djangoproject.com/en/dev/internals/contributing/triaging-
tickets/

Thank you!
--
Ticket URL: <https://code.djangoproject.com/ticket/36921#comment:2>

Django

unread,
Feb 11, 2026, 4:36:47 PM (10 hours ago) Feb 11
to django-...@googlegroups.com
#36921: KeyError when adding new objects two relations deep via inlines but the
intermediate model is not registered with the admin
---------------------------------+---------------------------------------
Reporter: Jacob Walls | Owner: Sean Helvey
Type: Bug | Status: assigned
Component: contrib.admin | Version: dev
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
---------------------------------+---------------------------------------
Changes (by Sean Helvey):

* needs_tests: 0 => 1
* owner: (none) => Sean Helvey
* stage: Unreviewed => Accepted
* status: new => assigned

--
Ticket URL: <https://code.djangoproject.com/ticket/36921#comment:3>

Django

unread,
Feb 11, 2026, 5:16:22 PM (10 hours ago) Feb 11
to django-...@googlegroups.com
#36921: KeyError when adding new objects two relations deep via inlines but the
intermediate model is not registered with the admin
---------------------------------+---------------------------------------
Reporter: Jacob Walls | Owner: Sean Helvey
Type: Bug | Status: assigned
Component: contrib.admin | Version: dev
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
---------------------------------+---------------------------------------
Changes (by Sean Helvey):

* has_patch: 0 => 1

Comment:

Created PR: https://github.com/django/django/pull/20679.
--
Ticket URL: <https://code.djangoproject.com/ticket/36921#comment:4>

Django

unread,
Feb 11, 2026, 5:34:07 PM (9 hours ago) Feb 11
to django-...@googlegroups.com
#36921: KeyError when adding new objects two relations deep via inlines but the
intermediate model is not registered with the admin
---------------------------------+---------------------------------------
Reporter: Jacob Walls | Owner: Sean Helvey
Type: Bug | Status: assigned
Component: contrib.admin | Version: dev
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
---------------------------------+---------------------------------------
Changes (by Jacob Walls):

* needs_better_patch: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/36921#comment:5>

Django

unread,
Feb 11, 2026, 6:04:46 PM (9 hours ago) Feb 11
to django-...@googlegroups.com
#36921: KeyError when adding new objects two relations deep via inlines but the
intermediate model is not registered with the admin
-------------------------------------+-------------------------------------
Reporter: Jacob Walls | Owner: Sean
| Helvey
Type: Bug | Status: assigned
Component: contrib.admin | Version: dev
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* needs_better_patch: 1 => 0
* needs_tests: 1 => 0
* stage: Accepted => Ready for checkin

--
Ticket URL: <https://code.djangoproject.com/ticket/36921#comment:6>

Django

unread,
Feb 11, 2026, 6:07:50 PM (9 hours ago) Feb 11
to django-...@googlegroups.com
#36921: KeyError when adding new objects two relations deep via inlines but the
intermediate model is not registered with the admin
-------------------------------------+-------------------------------------
Reporter: Jacob Walls | Owner: Sean
| Helvey
Type: Bug | Status: closed
Component: contrib.admin | Version: dev
Severity: Release blocker | Resolution: fixed
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by GitHub <noreply@…>):

* resolution: => fixed
* status: assigned => closed

Comment:

In [changeset:"380d77cccefbe185ddb3f9368d8fdeb7b7cf7108" 380d77c]:
{{{#!CommitTicketReference repository=""
revision="380d77cccefbe185ddb3f9368d8fdeb7b7cf7108"
Fixed #36921 -- Fixed KeyError in inline form for model not registered
with admin.

Regression in b1ffa9a9d78b0c2c5ad6ed5a1d84e380d5cfd010.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/36921#comment:7>
Reply all
Reply to author
Forward
0 new messages