首页 > 解决方案 > 在 Django admin 中为子模型添加按钮

问题描述

姜戈 1.11。我有 2 个模型,Foo并且Bar

class Foo(models.Model):
    name = models.CharField()

class Bar(models.Model):
    name = models.CharField()
    foo = models.ForeignKey(Foo)

FooDjango admin 的详细信息页面中,我Bar在详细信息下方列出了所有 child 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 中做到这一点?

标签: pythondjango

解决方案


为此,django 允许您在管理类中包含内。例如,以下将在表格中显示相关对象,而不显示用于更改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。


推荐阅读