我定义了几个模型:期刊,卷,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
更新: 自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
.
我希望它对其他人有用.
乔瓦尼
更新:
从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
这对我有用.
这是基于其他一些答案的可重用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 1.8+中,现在更容易了.只需添加show_change_link = True
到您的TabularInline
或StackedInline
子类,如下所示:
class VolumeInline(admin.TabularInline): fields = ['volumenumber'] model = Volume extra = 1 show_change_link = True
如果模型有自己的注册项,Django会自动为每个内联项添加一个完整更改表单的链接ModelAdmin
.