Skip to main content
 首页 » 编程设计

python之在 Django 管理中为子模型添加按钮

2024年12月31日26Leo_wl

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 详细信息页面中,我列出了 Foo 详细信息下的所有子 Bar:

@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。这可行,但我想要的是在添加新的 Bar 时自动预填充 Foo 下拉列表。 IE。我想向当前打开的 Foo 添加一个 Bar。我如何在 Django 中执行此操作?

请您参考如下方法:

为此,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 provides two subclasses of InlineModelAdmin and they are:

  • TabularInline
  • StackedInline

The difference between these two is merely the template used to render them.

如果这些内联不能满足您的需求,您可以创建自己的内联以使用自定义模板。

from django.contrib.admin.options import InlineModelAdmin 
 
 
class ListInlineAdmin(InlineModelAdmin): 
    template = 'admin/edit_inline/list.html' 

然后在新的 list.html 模板中,您可以让它显示对象名称并根据需要更改 URL。