当前位置:  开发笔记 > 编程语言 > 正文

Django InlineModelAdmin:部分显示内联模型并链接到完整模型

如何解决《DjangoInlineModelAdmin:部分显示内联模型并链接到完整模型》经验,为你挑选了4个好方法。

我定义了几个模型:期刊,卷,volume_scanInfo等.

日志可以拥有更多卷,而卷可以拥有更多scanInfo.

我想做的是:

在期刊的管理页面中我想要内联的卷列表(完成)

将上一个列表的每个卷连接到其管理页面,我可以在其中显示表单以编辑卷以及内联的"扫描信息"列表.

所以我希望有类似的东西:

Journal #1 admin page
[name]
[publisher]
[url]
.....
list of volumes inline
    [volume 10] [..(other fields)..]   Full record
    [volume 20] [..(other fields)..]   Full record

然后

Volume #20 admin page
[volume number]
[..(other fields)...]
......
list of the scan info inline
    [scan info 33] [..(other fields)..]   Full record
    [scan info 44] [..(other fields)..]   Full record

我尝试做的是定义一个模型方法,该方法创建代码并尝试在管理中定义"volume inline"的类中使用它,但它不起作用.

换一种说法

模型"卷"有类似于:

def selflink(self):
    return 'Full record' % self.vid
selflink.allow_tags = True

class VolumeInline(admin.TabularInline):
    fields = ['volumenumber', 'selflink']
    model = Volume
    extra = 1

但是这会产生以下错误:

Exception Value: 'VolumeInline.fields' refers to field 'selflink' that is missing from the form.

任何的想法?

谢谢Giovanni



1> Giovanni Di ..:

更新: 自Django 1.8以来,这是内置的.

请参阅此答案和官方文档.

老答案:

最后,我找到了一个简单的解决方案.

我创建了一个新模板,称为linked.html副本,tabular.html我添加了此代码来创建链接.

{% if inline_admin_form.original.pk %}
          
              Full record
          
{% endif %}

然后我创建了一个LinkedInline继承的新模型InlineModelAdmin

#override of the InlineModelAdmin to support the link in the tabular inline
class LinkedInline(admin.options.InlineModelAdmin):
    template = "admin/linked.html"
    admin_model_path = None

    def __init__(self, *args):
        super(LinkedInline, self).__init__(*args)
        if self.admin_model_path is None:
            self.admin_model_path = self.model.__name__.lower()

然后当我定义一个新的内联时,我只需要使用my LinkedInline而不是正常InlineModelAdmin.

我希望它对其他人有用.

乔瓦尼


不,如果你在完整的卷管理页面内,保存后你会留在那里.但由于该卷具有日志的外键,因此我扩展了外键表单以打印返回日志的链接,因此您只需单击一下即可返回.

2> hurturk..:

更新:

从Django 1.8开始,它现在已经内置了.

Django的答案<= 1.7:

使用条件大小写将代码保存在models.py中:

def selflink(self):
    if self.id:
        return "Edit" % str(self.id)
    else:
        return "Not present"

selflink.allow_tags = True

admin.py中,将selflink添加为只读字段:

class VolumeInline(admin.TabularInline):
    readonly_fields = ['selflink',]
    model = Volume

这对我有用.


如果你使用`fields`选项,你需要把它放在`readonly_fields`之后

3> Jack Cushman..:

这是基于其他一些答案的可重用mixin.这很方便,因为它适用于Tabular和Stacked内联,并且不会破坏您的模型或管理代码.

# put this somewhere like admin_helpers.py
from django.core.urlresolvers import reverse

class InlineEditLinkMixin(object):
    readonly_fields = ['edit_details']
    edit_label = "Edit"
    def edit_details(self, obj):
        if obj.id:
            opts = self.model._meta
            return "%s" % (reverse(
                'admin:%s_%s_change' % (opts.app_label, opts.object_name.lower()),
                args=[obj.id]
            ), self.edit_label)
        else:
            return "(save to edit details)"
    edit_details.allow_tags = True

# admin.py

class VolumeInline(InlineEditLinkMixin, admin.TabularInline):
    fields = ['foo', 'bar', 'edit_details']

class JournalAdmin(admin.ModelAdmin):
    inlines = [VolumeInline]

class ScanInfoInline(InlineEditLinkMixin, admin.StackedInline):
    fields = ['foo', 'bar', 'edit_details']

class JournalAdmin(admin.ModelAdmin):
    inlines = [ScanInfoInline]


非常有帮助和整洁.我需要在你的代码中添加这个`来自django.core.urlresolvers import reverse`

4> Carl Meyer..:

在Django 1.8+中,现在更容易了.只需添加show_change_link = True到您的TabularInlineStackedInline子类,如下所示:

class VolumeInline(admin.TabularInline):
    fields = ['volumenumber']
    model = Volume
    extra = 1
    show_change_link = True

如果模型有自己的注册项,Django会自动为每个内联项添加一个完整更改表单的链接ModelAdmin.

推荐阅读
k78283381
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有