#15665: Inline admins are broken when primary key is not an AutoField and not editable. ------------------------------------------+--------------------------- Reporter: sebastian_noack | Owner: nobody Status: new | Milestone: Component: Database layer (models, ORM) | Version: 1.2 Keywords: | Triage Stage: Unreviewed Has patch: 0 | ------------------------------------------+--------------------------- For each inline object, a hidden field for its primary key (if it is an AutoField) is included in the form. But if you inherit from a concrete model that has a custom (not AutoField) primary key, you end up in a situation where you have a primary key which is a OneToOneField that is not editable in the admin.
{{{ #!python from django.db import models class Event(models.Model): name = models.CharField(max_length=100, primary_key=True) def __unicode__(self): return self.name class Person(models.Model): name = models.CharField(max_length=100, primary_key=True) def __unicode__(self): return self.name class Visitor(Person): event = models.ForeignKey(Event) def __unicode__(self): return u"'%s' at '%s'" % (self.person_ptr, self.event) }}} {{{ #!python from django.contrib import admin class VisitorInline(admin.StackedInline): model = Visitor class EventAdmin(admin.ModelAdmin): inlines = [VisitorInline] admin.site.register(Event, EventAdmin) }}} In that case there is no element in the form that holds the primary key and you get the Exception below, when you try to save an existing object in the admin. {{{ Traceback (most recent call last): File "/home/sebastian/djacap/fam/src/famtest/django/core/servers/basehttp.py", line 280, in run self.result = application(self.environ, self.start_response) File "/home/sebastian/djacap/fam/src/famtest/django/core/servers/basehttp.py", line 674, in __call__ return self.application(environ, start_response) File "/home/sebastian/djacap/fam/src/famtest/django/core/handlers/wsgi.py", line 241, in __call__ response = self.get_response(request) File "/home/sebastian/djacap/fam/src/famtest/django/core/handlers/base.py", line 141, in get_response return self.handle_uncaught_exception(request, resolver, sys.exc_info()) File "/home/sebastian/djacap/fam/src/famtest/django/core/handlers/base.py", line 165, in handle_uncaught_exception return debug.technical_500_response(request, *exc_info) File "/home/sebastian/djacap/fam/src/famtest/django/views/debug.py", line 58, in technical_500_response html = reporter.get_traceback_html() File "/home/sebastian/djacap/fam/src/famtest/django/core/handlers/base.py", line 100, in get_response response = callback(request, *callback_args, **callback_kwargs) File "/home/sebastian/djacap/fam/src/famtest/django/contrib/admin/options.py", line 239, in wrapper return self.admin_site.admin_view(view)(*args, **kwargs) File "/home/sebastian/djacap/fam/src/famtest/django/utils/decorators.py", line 76, in _wrapped_view response = view_func(request, *args, **kwargs) File "/home/sebastian/djacap/fam/src/famtest/django/views/decorators/cache.py", line 69, in _wrapped_view_func response = view_func(request, *args, **kwargs) File "/home/sebastian/djacap/fam/src/famtest/django/contrib/admin/sites.py", line 190, in inner return view(request, *args, **kwargs) File "/home/sebastian/djacap/fam/src/famtest/django/utils/decorators.py", line 21, in _wrapper return decorator(bound_func)(*args, **kwargs) File "/home/sebastian/djacap/fam/src/famtest/django/utils/decorators.py", line 76, in _wrapped_view response = view_func(request, *args, **kwargs) File "/home/sebastian/djacap/fam/src/famtest/django/utils/decorators.py", line 17, in bound_func return func(self, *args2, **kwargs2) File "/home/sebastian/djacap/fam/src/famtest/django/db/transaction.py", line 299, in _commit_on_success res = func(*args, **kw) File "/home/sebastian/djacap/fam/src/famtest/django/contrib/admin/options.py", line 890, in change_view queryset=inline.queryset(request)) File "/home/sebastian/djacap/fam/src/famtest/django/forms/models.py", line 705, in __init__ queryset=qs) File "/home/sebastian/djacap/fam/src/famtest/django/forms/models.py", line 429, in __init__ super(BaseModelFormSet, self).__init__(**defaults) File "/home/sebastian/djacap/fam/src/famtest/django/forms/formsets.py", line 47, in __init__ self._construct_forms() File "/home/sebastian/djacap/fam/src/famtest/django/forms/formsets.py", line 97, in _construct_forms self.forms.append(self._construct_form(i)) File "/home/sebastian/djacap/fam/src/famtest/django/forms/models.py", line 718, in _construct_form form = super(BaseInlineFormSet, self)._construct_form(i, **kwargs) File "/home/sebastian/djacap/fam/src/famtest/django/forms/models.py", line 446, in _construct_form pk = self.data[pk_key] File "/home/sebastian/djacap/fam/src/famtest/django/utils/datastructures.py", line 235, in __getitem__ raise MultiValueDictKeyError("Key %r not found in %r" % (key, self)) MultiValueDictKeyError: "Key 'visitor_set-0-person_ptr' not found in <QueryDict: {u'visitor_set-__prefix__-event': [u'FOSDEM'], u'name': [u'FOSDEM'], u'visitor_set-0-name': [u'Me'], u'visitor_set-3-event': [u'FOSDEM'], u'visitor_set-3-name': [u''], u'visitor_set-1-event': [u'FOSDEM'], u'visitor_set-1-name': [u''], u'visitor_set-2-event': [u'FOSDEM'], u'visitor_set-2-name': [u''], u'visitor_set-INITIAL_FORMS': [u'1'], u'visitor_set-TOTAL_FORMS': [u'4'], u'csrfmiddlewaretoken': [u'85dd78ff278138c4c70f2d1c8107bd95'], u'visitor_set-0-event': [u'FOSDEM'], u'_continue': [u'Save and continue editing'], u'visitor_set- MAX_NUM_FORMS': [u''], u'visitor_set-__prefix__-name': [u'']}>" }}} I found following line in ''admin/edit_inline/tabular.html'' and ''admin/edit_inline/stacked.html''. {{{ {% if inline_admin_form.has_auto_field %}{{ inline_admin_form.pk_field.field }}{% endif %} }}} Removing the check for ''has_auto_field'' fixed the error described above, but leads to wrong behavior, when modifying the value of the concrete base class's primary key (the ''name'' field in the example above) in the inline admin, resulting in a new entry. I have reproduced that issue with django 1.2.3, 1.2.4, 1.2.5 and the latest version from SVN. -- Ticket URL: <http://code.djangoproject.com/ticket/15665> 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 django-updates@googlegroups.com. To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-updates?hl=en.