#14065: Admin: Explicit primary_key in child model breaks admin inlines
(MultiValueDictKeyError)
--------------------------+-------------------------------------------------
 Reporter:  intgr         |       Owner:  nobody    
   Status:  new           |   Milestone:            
Component:  Contrib apps  |     Version:  1.2       
 Keywords:                |       Stage:  Unreviewed
Has_patch:  0             |  
--------------------------+-------------------------------------------------
 Let's say I have a parent-child model, where the child model has an
 explicit `primary_key=True` field. The parent admin page contains an
 inline for editing the child. Saving, or deleting the child, fails with a
 "MultiValueDictKeyError", because the primary key of the child is not
 being submitted. Full model&admin included below.

 {{{
 Environment:

 Request Method: POST
 Request URL: http://localhost:8001/admin/myapp/parent/1/
 Django Version: 1.2.1
 Python Version: 2.6.5
 Installed Applications:
 ['django.contrib.auth',
  'django.contrib.contenttypes',
  'django.contrib.sessions',
  'django.contrib.sites',
  'django.contrib.messages',
  'django.contrib.admin',
  'wtf.myapp']
 Installed Middleware:
 ('django.middleware.common.CommonMiddleware',
  'django.contrib.sessions.middleware.SessionMiddleware',
  'django.middleware.csrf.CsrfViewMiddleware',
  'django.contrib.auth.middleware.AuthenticationMiddleware',
  'django.contrib.messages.middleware.MessageMiddleware')

 Exception Type: MultiValueDictKeyError at /admin/myapp/parent/1/
 Exception Value: "Key 'child_set-0-child_id' not found in
   <QueryDict: {u'child_set-0-name': [u'bar'], u'child_set-3-name': [u''],
 u'child_set-3-parent': [u'1'],
     u'child_set-MAX_NUM_FORMS': [u''], u'name': [u'foo'], u'_save':
 [u'Save'], u'child_set-__prefix__-name': [u''],
     u'child_set-__prefix__-parent': [u'1'], u'child_set-2-parent': [u'1'],
 u'child_set-2-name': [u''],
     u'child_set-0-parent': [u'1'], u'child_set-TOTAL_FORMS': [u'4'],
 u'child_set-1-parent': [u'1'],
     u'csrfmiddlewaretoken': [u'055944541276fbcb6a8a6d2fcb54968a'], u
 'child_set-INITIAL_FORMS': [u'1'],
     u'child_set-1-name': [u'']}>"

 Traceback:
 File "/usr/lib/python2.6/site-packages/django/core/handlers/base.py" in
 get_response
   100.                     response = callback(request, *callback_args,
 **callback_kwargs)
 File "/usr/lib/python2.6/site-packages/django/contrib/admin/options.py" in
 wrapper
   239.                 return self.admin_site.admin_view(view)(*args,
 **kwargs)
 File "/usr/lib/python2.6/site-packages/django/utils/decorators.py" in
 _wrapped_view
   76.                     response = view_func(request, *args, **kwargs)
 File "/usr/lib/python2.6/site-packages/django/views/decorators/cache.py"
 in _wrapped_view_func
   69.         response = view_func(request, *args, **kwargs)
 File "/usr/lib/python2.6/site-packages/django/contrib/admin/sites.py" in
 inner
   190.             return view(request, *args, **kwargs)
 File "/usr/lib/python2.6/site-packages/django/utils/decorators.py" in
 _wrapper
   21.             return decorator(bound_func)(*args, **kwargs)
 File "/usr/lib/python2.6/site-packages/django/utils/decorators.py" in
 _wrapped_view
   76.                     response = view_func(request, *args, **kwargs)
 File "/usr/lib/python2.6/site-packages/django/utils/decorators.py" in
 bound_func
   17.                 return func(self, *args2, **kwargs2)
 File "/usr/lib/python2.6/site-packages/django/db/transaction.py" in
 _commit_on_success
   299.                     res = func(*args, **kw)
 File "/usr/lib/python2.6/site-packages/django/contrib/admin/options.py" in
 change_view
   890.
 queryset=inline.queryset(request))
 File "/usr/lib/python2.6/site-packages/django/forms/models.py" in __init__
   698.                                                 queryset=qs)
 File "/usr/lib/python2.6/site-packages/django/forms/models.py" in __init__
   423.         super(BaseModelFormSet, self).__init__(**defaults)
 File "/usr/lib/python2.6/site-packages/django/forms/formsets.py" in
 __init__
   47.         self._construct_forms()
 File "/usr/lib/python2.6/site-packages/django/forms/formsets.py" in
 _construct_forms
   97.             self.forms.append(self._construct_form(i))
 File "/usr/lib/python2.6/site-packages/django/forms/models.py" in
 _construct_form
   711.         form = super(BaseInlineFormSet, self)._construct_form(i,
 **kwargs)
 File "/usr/lib/python2.6/site-packages/django/forms/models.py" in
 _construct_form
   439.             pk = self.data[pk_key]
 File "/usr/lib/python2.6/site-packages/django/utils/datastructures.py" in
 __getitem__
   233.             raise MultiValueDictKeyError("Key %r not found in %r" %
 (key, self))

 }}}

 == model.py ==
 {{{
 from django.db import models

 class Parent(models.Model):
     name = models.CharField(max_length=128)

 class Child(models.Model):
     child_id = models.IntegerField(primary_key=True)
     # this also fails: id = models.IntegerField(primary_key=True,
 db_column='child_id')
     name = models.CharField(max_length=128)
     parent = models.ForeignKey(Parent)
 }}}

 == admin.py ==
 {{{
 from wtf.myapp.models import *
 from django.contrib import admin

 class ChildInline(admin.TabularInline):
   model = Child
   fields = ['parent', 'name']

 class ParentAdmin(admin.ModelAdmin):
   inlines = [ChildInline]
   fields = ['name']
 admin.site.register(Parent, ParentAdmin)
 }}}

 == Reproducing ==
  1. Create project and app, enable admin, add the above files and syncdb.
  2. Go to the admin interface and create a new Parent object
  3. Add a new child object to the parent
  4. Save
  5. Go back the the list
  6. Open the same parent object again
  7. Click save. Bam!

-- 
Ticket URL: <http://code.djangoproject.com/ticket/14065>
Django <http://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 post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to