Django管理不同的内联更改并添加视图

时间:2010-02-10 08:59:00

标签: django django-admin django-forms inlines

我需要单独的视图来添加和更改页面。在添加页面中,我想从内联formset中排除一些字段。我准备了两个TabularInline类,其中一个包含属性'exclude'。我尝试按如下方式使用它们:

class BoxAdmin(admin.ModelAdmin):
    def change_view(self, request, obj_id):
        self.inlines=[ItemChangeInline,]
        return super(BoxAdmin, self).change_view(self.request, obj_id)
    def add_view(self, request):
        self.inlines=[ItemAddInline,]
        return super(BoxAdmin, self).add_view(self, request)

没有效果(根本没有显示内联)。

6 个答案:

答案 0 :(得分:17)

它适用于Django 1.5+并且似乎很好&优雅:

// admin.py
class BoxAdmin(ModelAdmin):

    inlines = ()

    def change_view(self, request, object_id, form_url='', extra_context=None):
        self.inlines = (ItemChangeInline, )
        return super(BoxAdmin, self).change_view(request, object_id)

    def add_view(self, request, form_url='', extra_context=None):
        self.inlines = (ItemAddInline, )
        return super(BoxAdmin, self).add_view(request)

希望它对任何人都有用

答案 1 :(得分:7)

以下是似乎有效的代码:

class BoxAdmin(admin.ModelAdmin):
   def change_view(self, request, obj_id):
        self.inlines=[ItemChangeInline,]
        for inline_class in self.inlines:
            inline_instance = inline_class(self.model, self.admin_site)
            self.inline_instances.append(inline_instance)
        return super(BoxAdmin, self).change_view(request, obj_id)
    def add_view(self, request):
        self.inlines=[ItemAddInline,]
        for inline_class in self.inlines:
            inline_instance = inline_class(self.model, self.admin_site)
            self.inline_instances.append(inline_instance)
        return super(BoxAdmin, self).add_view(request)

然而,这看起来不够优雅,导致这部分:

            for inline_class in self.inlines:
            inline_instance = inline_class(self.model, self.admin_site)
            self.inline_instances.append(inline_instance)

是来自admin.ModelAdmin的 init 方法的复制粘贴(因此它运行两次)。

答案 2 :(得分:1)

为什么在add_view中您有.add_view(self, request)并且在更改视图中您有.change_view(self.request, ..)?我相信,你在add_view中不需要自己,因为你使用super。

答案 3 :(得分:0)

我遇到过一种情况,我需要根据您为特定故事提供的管理网站显示内联。

扩展了alekwisnia的答案,我能够使用以下代码获得为Django 1.3工作的动态内联:

在highlight / admin.py

class HighlightInline(generic.GenericTabularInline):
    model = Highlight
    extra = 1
    max_num = 4
    fields = ('order', 'highlight')
    template = 'admin/highlights/inline.html'

class HighlightAdmin(admin.ModelAdmin):
    def regulate_highlight_inlines(self):
        highlights_enabled = Setting.objects.get_or_default('highlights_enabled', default='')
        highlight_inline_instance = HighlightInline(self.model, self.admin_site)
        highlight_found = any(isinstance(x, HighlightInline) for x in self.inline_instances)
        if highlights_enabled.strip().lower() == 'true':
            if not highlight_found:
                self.inline_instances.insert(0, highlight_inline_instance)
        else:
            if highlight_found:
                self.inline_instances.pop(0)
        print self.inline_instances

    def change_view(self, request, object_id, form_url='', extra_context=None):
        self.regulate_highlight_inlines()
        return super(HighlightAdmin, self).change_view(request, object_id)

    def add_view(self, request, form_url='', extra_context=None):
        self.regulate_highlight_inlines()   
        return super(HighlightAdmin, self).add_view(request, form_url, extra_context)

在故事/ admin.py

class StoryAdmin(HighlightAdmin):

有一点需要注意的是,我不仅仅是在操作内联类(HighlightInline),而是在改变内联实例(HighlightInline(self.model,self.admin_site))。这是因为在管理类的初始构建期间,django已经基于内联类列表构建了内联实例列表。

答案 4 :(得分:0)

Django 1.3的另一个解决方案

class BoxAdmin(admin.ModelAdmin):

    def change_view(self, request, object_id, form_url='', extra_context=None):
        self.inline_instances = [ItemChangeInline(self.model, self.admin_site)]
        return super(BoxAdmin, self).change_view(request, object_id, extra_context)

    def add_view(self, request, form_url='', extra_context=None):
        self.inline_instances = [ItemAddInline(self.model, self.admin_site)]
        return super(BoxAdmin, self).add_view(request, form_url, extra_context)

答案 5 :(得分:0)

受你们的启发, 我能够向admin.site添加更多自定义视图。

很多时候,只希望addchange页的设置不同,而不是真正的多余视图

# admin.py
class FooAdmin(admin.ModelAdmin):
    ....
    def edit_tag(self, obj):              # add a Link tag to change-list page
        return mark_safe('<a href="{}?edit=True">Edit</a>'.format(obj.get_absolute_url()))

    edit_tag.short_description = u'Extra Action'

    def change_view(self, request, object_id, form_url='', extra_context=None):
        if request.GET.get('edit', False):
            self.readonly_fields = (
                'total_amount',
            )
            self.inlines = []
        else:
            self.readonly_fields = (
                'name', 'client', 'constructor', 'total_amount'
            )
            self.inlines = [TransactionInline]
        return super(ProjectAdmin, self).change_view(request, object_id)

    def add_view(self, request, form_url='', extra_context=None):
        self.readonly_fields = (
            'total_amount',
        )
        self.inlines = []
        return super(ProjectAdmin, self).add_view(request)

此后,我将有以下三种视图: enter image description here

  1. 添加视图-无需内联表单集,无需添加相关对象。 enter image description here

  2. 更改视图1 -具有内联表单集,仅用于添加内联数据(相关对象),该对象的字段为只读。 enter image description here

  3. 更改视图2 -不带内联表单集,仅用于更改对象。 enter image description here

真的很简单,我们可以做的更多,谢谢大家。