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
- Create project and app, enable admin, add the above files and syncdb.
- Go to the admin interface and create a new Parent object
- Add a new child object to the parent
- Save
- Go back the the list
- Open the same parent object again
- Click save. Bam!
Seems like a duplicate of #12599. You are using a
fields
option in you Child Inline that excludes your IntegerField (and as such, manually controllable) PK, this is similar to the case attached to that ticker where the reporter was excluding his IntegerField PK by using theexclude
option.