In the ModelAdmin
of my application i want to change the inlines of a change_view
based on a certain condition of the object.
class TextInline(generic.GenericStackedInline):
model = Text
class ImageInline(generic.GenericStackedInline):
model = Image
class VideoInline(generic.GenericStackedInline):
model = Video
class PageAdmin(models.ModelAdmin):
def add_view(self, request, form_url='', extra_context=None):
self.inlines = []
return super(PageAdmin, self).add_view(
request, form_url, extra_context)
def change_view(self, request, object_id, form_url='', extra_context=None):
obj = Page.objects.get(id=object_id)
if obj.page_type in ('foo', 'bar',):
self.inlines = [TextInline]
elif obj.page_type == 'baz':
self.inlines = [ImageInline, VideoInline]
return super(PageAdmin, self).change_view(
request, object_id, form_url, extra_context)
The add_view
works as expected, no inlines are displayed. The change_view
also displays the correct inlines on initial load and the correct inline instances after the first save. When the page is saved another time an MultiValueDictKeyError
is raised. Apparently complaining of the missing inline instances.
Traceback:
File "/path/to/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/path/to/django/contrib/admin/options.py" in wrapper
366. return self.admin_site.admin_view(view)(*args, **kwargs)
File "/path/to/django/utils/decorators.py" in _wrapped_view
91. response = view_func(request, *args, **kwargs)
File "/path/to/django/views/decorators/cache.py" in _wrapped_view_func
89. response = view_func(request, *args, **kwargs)
File "/path/to/django/contrib/admin/sites.py" in inner
196. return view(request, *args, **kwargs)
File "/path/to/presentation/admin.py" in change_view
151. request, object_id, form_url, extra_context)
File "/path/to/django/utils/decorators.py" in _wrapper
25. return bound_func(*args, **kwargs)
File "/path/to/django/utils/decorators.py" in _wrapped_view
91. response = view_func(request, *args, **kwargs)
File "/path/to/django/utils/decorators.py" in bound_func
21. return func(self, *args2, **kwargs2)
File "/path/to/django/db/transaction.py" in inner
209. return func(*args, **kwargs)
File "/path/to/django/contrib/admin/options.py" in change_view
1049. queryset=inline.queryset(request))
File "/path/to/django/contrib/contenttypes/generic.py" in __init__
402. prefix=prefix
File "/path/to/django/forms/models.py" in __init__
424. super(BaseModelFormSet, self).__init__(**defaults)
File "/path/to/django/forms/formsets.py" in __init__
50. self._construct_forms()
File "/path/to/django/forms/formsets.py" in _construct_forms
115. self.forms.append(self._construct_form(i))
File "/path/to/django/forms/models.py" in _construct_form
443. pk = self.data[pk_key]
File "/path/to/django/utils/datastructures.py" in __getitem__
258. raise MultiValueDictKeyError("Key %r not found in %r" % (key, self))
Exception Type: MultiValueDictKeyError at /admin/presentation/page/5/
Exception Value: "Key 'presentation-text-content_type-object_id-0-id' not found in <QueryDict: {u'status': [u'2'], u'presentation-text-content_type-object_id-1-text': [u'xxx'], u'title': [u'y'], u'presentation-text-content_type-object_id-0-text': [u'xx'], u'presentation-text-content_type-object_id-__prefix__-ordering': [u''], u'presentation-text-content_type-object_id-TOTAL_FORMS': [u'2'], u'presentation-text-content_type-object_id-0-ordering': [u''], u'presentation-text-content_type-object_id-1-ordering': [u''], u'presentation-text-content_type-object_id-__prefix__-text': [u''], u'presentation-text-content_type-object_id-MAX_NUM_FORMS': [u''], u'csrfmiddlewaretoken': [u'6f53e0394b9008494a53cf460826235c'], u'presentation': [u'1'], u'_continue': [u'Sichern und weiter bearbeiten'], u'presentation-text-content_type-object_id-INITIAL_FORMS': [u'1']}>"
My question is very similiar to this one which even provides a solution. Django 1.4 however changed the api, so that there is no ModelAdmin.inline_instances
anymore.
In Django 1.4 you can use ModelAdmin.get_inline_instances()
to retrieve a list of inline instances, but i can't figure out how to set them. Or is there anoher way of doing this in Django 1.4? There might be a reason for the api change.