#26934: Admin inline save fails when inline contains readonly primary key
-------------------------------+--------------------
     Reporter:  LeeKevin       |      Owner:  nobody
         Type:  Bug            |     Status:  new
    Component:  contrib.admin  |    Version:  1.9
     Severity:  Normal         |   Keywords:
 Triage Stage:  Unreviewed     |  Has patch:  0
Easy pickings:  0              |      UI/UX:  0
-------------------------------+--------------------
 '''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))
 }}}

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

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/051.8384e612467f24494147c7fdeff3cacf%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to