15

I need separate views for add and change page. In add page I'd like to exclude some fields from inline formset. I've prepared two TabularInline classes, one of them contains property 'exclude'. I tried to use them as follows:

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)

with no effect (no inline is shown at all).

4

6 回答 6

21

它适用于 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)

希望它对任何人都有用

于 2013-05-24T11:21:58.210 回答
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方法的复制粘贴(因此它运行两次)。

于 2010-02-10T10:24:38.693 回答
1

Why in add_view you have .add_view(self, request) and in change view you have .change_view(self.request, ..)? I believe, you don't need self in add_view, since you use super.

于 2010-02-10T09:25:00.293 回答
0

我有一种情况,我需要根据您为给定故事所在的管理站点显示内联。

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

在亮点/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 在 admin 类的初始构建过程中,已经根据内联类列表构建了内联实例列表。

于 2014-06-15T14:27:08.763 回答
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)

在此之后,我将拥有三个视图: 在此处输入图像描述

  1. 添加视图- 无需内联表单集,无需添加相关对象。 在此处输入图像描述

  2. 更改视图 1 - 使用内联表单集,仅用于添加内联数据(相关对象),对象的字段是只读的。 在此处输入图像描述

  3. 更改视图 2 - 没有内联表单集,仅用于更改对象。 在此处输入图像描述

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

于 2019-03-31T09:18:30.260 回答
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)
于 2016-03-29T14:08:06.620 回答