如何在Django管理面板中列出所有与外键相关的对象?

ash*_*aka 7 python django django-admin

我想用django管理面板实现一个非常简单的功能,但到目前为止我找不到正确的方法:

model.py

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

class Books(models.Model):
    title = models.CharField()
    author = models.ForeignKey(Author)
Run Code Online (Sandbox Code Playgroud)

admin.py

class AuthorAdmin(admin.ModelAdmin):
    pass
admin.site.register(Author, AuthorAdmin)
Run Code Online (Sandbox Code Playgroud)

如何在作者列表概述中为每个项目(作者)添加一个超链接,该链接指向显示特定作者所有书籍的视图?例如:

  • JK罗琳(书籍)
  • JRR Tolkien(书籍)

书籍是指向显示作者所有书籍的网站的超链接.

all*_*aps 8

您正在寻找ModelAdmin.list_filter.

设置list_filter以激活管理员更改列表页面右侧边栏中的过滤器.listfilter可以是字段名,其中指定的字段应该是BooleanField,CharField,DateField,DateTimeField,IntegerField,ForeignKey或ManyToManyField,例如:

 # Add a list filter author to BookAdmin.
 # Now you can filter books by author.
 class BookAdmin(ModelAdmin):
    list_filter = ('author', )
Run Code Online (Sandbox Code Playgroud)

现在,您可以使用@Wolph建议在作者list_display中添加链接.此链接指向由作者过滤的图书清单:

# Add hyperlinks to AuthorAdmin.
# Now you can jump to the book list filtered by autor. 
class AuthorAdmin(admin.ModelAdmin):
    def authors(self):
        return '<a href="/admin/appname/book/?author__id__exact=%d">%s</a>' % (self.author_id, self.author)
    authors.allow_tags = True
Run Code Online (Sandbox Code Playgroud)

替代方案.要保存点击,您还可以直接指向书籍的更改视图:

class Books(models.Model):
    title = models.CharField()
    author = models.ForeignKey(Author)

def get_admin_url(self):
    return "/admin/appname/books/%d/" %self.id


class BookAdmin(admin.ModelAdmin):
    def authors(self):
        html = ""
        for obj in Books.objects.filter(author__id_exact=self.id):
            html += '<p><a href="%s">%s</a></p>' %(obj.get_admin_url(), obj.title)
        return html
    authors.allow_tags = True

    list_display = ['title', authors]
Run Code Online (Sandbox Code Playgroud)

免责声明:未经测试,但如果您修复错字,它将起作用!:)

请注意,这些链接也可以在管理员的其他位置注入.将其添加到窗口小部件时,您可以从更改视图转到更改视图.


Jos*_*etz 5

研究实现InlineModelAdmin对象。

# admin.py
class BooksInline(admin.TabularInline):
    model = Books

class AuthorAdmin(admin.ModelAdmin):
    inlines = [BooksInline]
Run Code Online (Sandbox Code Playgroud)

根据OP的评论编辑了答案:

class AuthorAdmin(admin.ModelAdmin):
    list_display = ['name', 'books_published']

    def books_published(self, obj):
        redirect_url = reverse('admin:books_changelist')
        extra = "?author__id__exact=%d" % (obj.id)
        return "<a href='%s'>Books by author</a>" % (redirect_url + extra)

    books_published.allow_tags = True
Run Code Online (Sandbox Code Playgroud)