Django 1.11。我有2个模型,Foo
和Bar
:
class Foo(models.Model):
name = models.CharField()
class Bar(models.Model):
name = models.CharField()
foo = models.ForeignKey(Foo)
在Django管理员的Foo
详细信息页面中,我在Bar
详细信息下面列出了所有子Foo
:
@admin.register(Foo)
class FooAdmin(admin.ModelAdmin):
def bars(self):
html = ''
bs = self.bar_set.all()
for b in bs:
html += '<a href="%s">%s</a><br>' % (reverse('admin:app_bar_change', args=(b.id,)), b.name)
html += '<a href="%s">Add a bar</button>' % (reverse('admin:app_bar_add'))
return html
bars.allow_tags = True
fields = ('name', bars)
readonly_fields = (bars,)
如您所见,我还添加了一个按钮来添加新的Bar
。这可行,但是我想要的是在添加新的Foo
时自动预填充Bar
下拉列表。即我想向当前打开的Bar
添加一个Foo
。如何在Django中做到这一点?
答案 0 :(得分:2)
为此django,您可以在管理类中加入inlines。例如,以下内容将在表中显示相关对象,而不显示用于更改name
字段的值的表格;
class BarInline(admin.TabularInline):
model = Bar
fields = (
'name'
)
readonly_fields = (
'name'
)
show_change_link = True
@admin.register(Foo)
class FooAdmin(admin.ModelAdmin):
fields = ('name', )
inlines = [
BarInline,
]
通过设置show_change_link
,您可以显示内联对象的更改链接,我相信这是您真正想要的。
Django提供了
InlineModelAdmin
的两个子类,它们是:
TabularInline
StackedInline
这两者之间的区别只是用于渲染它们的模板。
如果这些内联不能满足您的需求,则可以创建自己的内联以使用自定义模板。
from django.contrib.admin.options import InlineModelAdmin
class ListInlineAdmin(InlineModelAdmin):
template = 'admin/edit_inline/list.html'
然后在新的list.html
模板中,您可以获取它以显示对象名称并根据需要更改URL。
答案 1 :(得分:-1)
我在this SO answer中找到了解决方案。可以在URL的查询字符串中指定预填充的字段。所以我的代码现在看起来像这样:
HH:mm:ss
编辑:我需要首先检查实例是否具有if self.id:
html += '<a href="%s?foo=%d">Add a bar</a>' % (reverse('admin:app_bar_add'), self.id)
,即实例已经保存。