Gio*_*lia 32 python django django-admin
我定义了几个模型:期刊,卷,volume_scanInfo等.
日志可以拥有更多卷,而卷可以拥有更多scanInfo.
我想做的是:
所以我希望有类似的东西:
Journal #1 admin page
[name]
[publisher]
[url]
.....
list of volumes inline
[volume 10] [..(other fields)..] <a href="/link/to/volume/10">Full record</a>
[volume 20] [..(other fields)..] <a href="/link/to/volume/20">Full record</a>
Run Code Online (Sandbox Code Playgroud)
然后
Volume #20 admin page
[volume number]
[..(other fields)...]
......
list of the scan info inline
[scan info 33] [..(other fields)..] <a href="/link/to/scaninfo/33">Full record</a>
[scan info 44] [..(other fields)..] <a href="/link/to/scaninfo/44">Full record</a>
Run Code Online (Sandbox Code Playgroud)
我尝试做的是定义一个模型方法,该方法创建代码并尝试在管理中定义"volume inline"的类中使用它,但它不起作用.
换一种说法
模型"卷"有类似于:
def selflink(self):
return '<a href="/admin/journaldb/volume/%s/">Full record</a>' % self.vid
selflink.allow_tags = True
Run Code Online (Sandbox Code Playgroud)
和
class VolumeInline(admin.TabularInline):
fields = ['volumenumber', 'selflink']
model = Volume
extra = 1
Run Code Online (Sandbox Code Playgroud)
但是这会产生以下错误:
Exception Value: 'VolumeInline.fields' refers to field 'selflink' that is missing from the form.
Run Code Online (Sandbox Code Playgroud)
任何的想法?
谢谢Giovanni
Gio*_*lia 29
更新: 自Django 1.8以来,这是内置的.
老答案:
最后,我找到了一个简单的解决方案.
我创建了一个新模板,称为linked.html副本,tabular.html我添加了此代码来创建链接.
{% if inline_admin_form.original.pk %}
<td class="{{ field.field.name }}">
<a href="/admin/{{ app_label }}/{{ inline_admin_formset.opts.admin_model_path }}/{{ inline_admin_form.original.pk }}/">Full record</a>
</td>
{% endif %}
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个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()
Run Code Online (Sandbox Code Playgroud)
然后当我定义一个新的内联时,我只需要使用my LinkedInline而不是正常InlineModelAdmin.
我希望它对其他人有用.
乔瓦尼
hur*_*urk 25
更新:
从Django 1.8开始,它现在已经内置了.
Django的答案<= 1.7:
使用条件大小写将代码保存在models.py中:
def selflink(self):
if self.id:
return "<a href='/link/to/volume/%s' target='_blank'>Edit</a>" % str(self.id)
else:
return "Not present"
selflink.allow_tags = True
Run Code Online (Sandbox Code Playgroud)
在admin.py中,将selflink添加为只读字段:
class VolumeInline(admin.TabularInline):
readonly_fields = ['selflink',]
model = Volume
Run Code Online (Sandbox Code Playgroud)
这对我有用.
Jac*_*man 13
这是基于其他一些答案的可重用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 "<a href='%s' target='_blank'>%s</a>" % (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]
Run Code Online (Sandbox Code Playgroud)
在Django 1.8+中,现在更容易了.只需添加show_change_link = True到您的TabularInline或StackedInline子类,如下所示:
class VolumeInline(admin.TabularInline):
fields = ['volumenumber']
model = Volume
extra = 1
show_change_link = True
Run Code Online (Sandbox Code Playgroud)
如果模型有自己的注册项,Django会自动为每个内联项添加一个完整更改表单的链接ModelAdmin.