﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
26934	Admin inline save fails when inline contains readonly primary key	Kevin Lee	nobody	"'''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))
}}}"	Bug	closed	contrib.admin	1.9	Normal	duplicate			Unreviewed	0	0	0	0	0	0
