Opened 8 years ago
Closed 8 years ago
#26934 closed Bug (duplicate)
Admin inline save fails when inline contains readonly primary key
Reported by: | Kevin Lee | Owned by: | nobody |
---|---|---|---|
Component: | contrib.admin | Version: | 1.9 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Example:
For an AbstractBaseCode model (password reset), the "code" field is as follows (note the primary_key argument):
code = models.CharField(_('code'), max_length=40, primary_key=True)
And the inline admin class is:
class PasswordResetCodeInline(admin.TabularInline): model = PasswordResetCode fieldsets = ( (None, { 'fields': ('code', 'created_at') }), ) readonly_fields = ('code', 'created_at') def has_add_permission(self, request): return False
When saving a user in Django admin, which contains the PasswordResetCodeInline, the following error is issued:
MultiValueDictKeyError at /admin/accounts/user/30/change/ "'passwordresetcode_set-0-code'" Exception location: /.../python3.5/site-packages/django/utils/datastructures.py in __getitem__, line 85
This occurs because line 587 in ModelForm._construct_form in forms/models.py looks for the primary key "code" within the editable fields. Since it is readonly, there is no input or hidden field passed along that includes the primary key.
Here is a snippet where the error occurs (on the last line):
def _construct_form(self, i, **kwargs): if self.is_bound and i < self.initial_form_count(): pk_key = "%s-%s" % (self.add_prefix(i), self.model._meta.pk.name) pk = self.data[pk_key]
Traceback:
Traceback (most recent call last): File "/.../lib/python3.5/site-packages/django/core/handlers/base.py", line 149, in get_response response = self.process_exception_by_middleware(e, request) File "/.../lib/python3.5/site-packages/django/core/handlers/base.py", line 147, in get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/.../lib/python3.5/site-packages/django/contrib/admin/options.py", line 541, in wrapper return self.admin_site.admin_view(view)(*args, **kwargs) File "/.../lib/python3.5/site-packages/django/utils/decorators.py", line 149, in _wrapped_view response = view_func(request, *args, **kwargs) File "/.../lib/python3.5/site-packages/django/views/decorators/cache.py", line 57, in _wrapped_view_func response = view_func(request, *args, **kwargs) File "/.../lib/python3.5/site-packages/django/contrib/admin/sites.py", line 244, in inner return view(request, *args, **kwargs) File "/.../lib/python3.5/site-packages/django/contrib/admin/options.py", line 1440, in change_view return self.changeform_view(request, object_id, form_url, extra_context) File "/.../lib/python3.5/site-packages/django/utils/decorators.py", line 67, in _wrapper return bound_func(*args, **kwargs) File "/.../lib/python3.5/site-packages/django/utils/decorators.py", line 149, in _wrapped_view response = view_func(request, *args, **kwargs) File "/.../lib/python3.5/site-packages/django/utils/decorators.py", line 63, in bound_func return func.__get__(self, type(self))(*args2, **kwargs2) File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/contextlib.py", line 30, in inner return func(*args, **kwds) File "/.../lib/python3.5/site-packages/django/contrib/admin/options.py", line 1377, in changeform_view if all_valid(formsets) and form_validated: File "/.../lib/python3.5/site-packages/django/forms/formsets.py", line 451, in all_valid if not formset.is_valid(): File "/.../lib/python3.5/site-packages/django/forms/formsets.py", line 316, in is_valid self.errors File "/.../lib/python3.5/site-packages/django/forms/formsets.py", line 290, in errors self.full_clean() File "/.../lib/python3.5/site-packages/django/forms/formsets.py", line 338, in full_clean form = self.forms[i] File "/.../lib/python3.5/site-packages/django/utils/functional.py", line 33, in __get__ res = instance.__dict__[self.name] = self.func(instance) File "/.../lib/python3.5/site-packages/django/forms/formsets.py", line 144, in forms for i in range(self.total_form_count())] File "/.../lib/python3.5/site-packages/django/forms/formsets.py", line 144, in <listcomp> for i in range(self.total_form_count())] File "/.../lib/python3.5/site-packages/django/forms/models.py", line 881, in _construct_form form = super(BaseInlineFormSet, self)._construct_form(i, **kwargs) File "/.../lib/python3.5/site-packages/django/forms/models.py", line 587, in _construct_form pk = self.data[pk_key] File "/.../lib/python3.5/site-packages/django/utils/datastructures.py", line 85, in __getitem__ raise MultiValueDictKeyError(repr(key))
Looks like a duplicate of #15665.