【问题标题】:Change admin inlines based on object condition using Django 1.4使用 Django 1.4 根据对象条件更改管理内联
【发布时间】:2012-06-24 22:18:02
【问题描述】:

在我的应用程序的ModelAdmin 中,我想根据对象的特定条件更改change_view 的内联。

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)

add_view 按预期工作,不显示内联。 change_view 还会在初始加载时显示正确的内联,并在 first 保存后显示正确的内联实例。当页面再次保存时,会引发MultiValueDictKeyError。显然是在抱怨缺少内联实例。

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']}>"

我的问题与this one 非常相似,它甚至提供了解决方案。然而,Django 1.4 更改了 api,因此不再有 ModelAdmin.inline_instances

在 Django 1.4 中,您可以使用 ModelAdmin.get_inline_instances() 检索内联实例列表,但我不知道如何设置它们。或者在 Django 1.4 中有另一种方法吗? api更改可能是有原因的。

【问题讨论】:

    标签: django django-admin django-1.4


    【解决方案1】:

    错误发生在

    File "/path/to/django/contrib/admin/options.py" in change_view
    1049.                                   queryset=inline.queryset(request))
    

    inline_instances 已经成功生成。

    通过检查您的POST

    >>> post = {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']}
    >>> sorted(post.keys())
    [u'_continue',
     u'csrfmiddlewaretoken',
     u'presentation',
     u'presentation-text-content_type-object_id-0-ordering',
     u'presentation-text-content_type-object_id-0-text',
     u'presentation-text-content_type-object_id-1-ordering',
     u'presentation-text-content_type-object_id-1-text',
     u'presentation-text-content_type-object_id-INITIAL_FORMS',
     u'presentation-text-content_type-object_id-MAX_NUM_FORMS',
     u'presentation-text-content_type-object_id-TOTAL_FORMS',
     u'presentation-text-content_type-object_id-__prefix__-ordering',
     u'presentation-text-content_type-object_id-__prefix__-text',
     u'status',
     u'title']
    

    没有像u'presentation-text-content_type-object_id-__prefix__-id' 这样的东西,但您的代码需要一个。所以最好检查 HTML、InlineModelAdmin 和模型,以找出为什么 POST 中没有这样的键。

    【讨论】:

    • 解决了我的问题。事实证明,我的内联使用了一个缺少必填字段的自定义表单。仍然不太明白这在第一次保存时如何使用内联...无论如何,非常感谢您为我指明了正确的方向!
    猜你喜欢
    • 2012-04-07
    • 2011-07-19
    • 2011-07-21
    • 2011-09-24
    • 2015-06-10
    • 1970-01-01
    • 2021-12-19
    • 2013-02-03
    • 1970-01-01
    相关资源
    最近更新 更多