﻿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
14065	Admin: non-AutoField primary_key in child model breaks admin inlines (MultiValueDictKeyError)	Marti Raudsepp	nobody	"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!
"		closed	Contrib apps	1.2		duplicate			Unreviewed	0	0	0	0	0	0
