如何在 django admin 中显示多个模型的更改列表?

Posted

技术标签:

【中文标题】如何在 django admin 中显示多个模型的更改列表?【英文标题】:How to display changelist of multiple models in django admin? 【发布时间】:2019-10-20 16:46:22 【问题描述】:

我需要在 django 管理员更改列表视图中显示多个模型。我想使用单个搜索框一次过滤所有这些。有什么简单的方法吗?

我的想法是从管理站点继承,向其中添加另一个视图并迭代修改后的 change_list.html 中的模型,但我无法导入模型和 ModelAdmins,因为我收到 django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet. 错误,所以我无法获得相同的django 用于呈现常规 change_list.html 的上下文。

正确的做法是什么?有没有更简单的方法?

【问题讨论】:

【参考方案1】:

从文档看来,没有简单的解决方案。(如果模型之间没有关系) https://docs.djangoproject.com/en/2.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields

因此,如果搜索是常用的,则构建一个特殊的模型/模型来组合可能被搜索的数据

【讨论】:

【参考方案2】:

正如 Ohad 所建议的,最可靠的方法可能是在您希望对象一起显示的模型之间建立正式的关系。您在这里有几个选择。本质上,您将想要制作一个大师班,然后从中继承您的模型。如果您的模型在本体上与父概念相关,这很有意义。例如:

出版 书籍 杂志问题

书籍和杂志都是出版物。它们都共享一些字段,例如标题和发布日期。但它们的不同之处在于,一本书通常只有一位作者,而杂志则有卷数和发行日期。 Django 已经使用Model inheritance 提供了几种不同的子类化方法。然而,在我自己尝试这些之后,我发现django-polymorphic extension 更好。这是一个使用 django-polymorphic 的 Django 3.0 应用程序的代码示例,该应用程序具有一个 Book 模型和一个 Magazine 模型,其中包含所有出版物的单个列表,显示系统中的所有书籍和杂志。

models.py

from django.db import models
from polymorphic.models import PolymorphicModel

class Publication(PolymorphicModel):
    title = models.CharField(max_length=256)
    publication_year = models.IntegerField()

class Book(Publication):
    author_first = models.CharField(max_length=256)
    author_last = models.CharField(max_length=256)

class Magazine(Publication):
    volume_number = models.IntegerField()
    issue_name = models.CharField(max_length=256)

admin.py

from django.contrib import admin
from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModelAdmin, PolymorphicChildModelFilter
from .models import Publication, Book, Magazine


class PublicationChildAdmin(PolymorphicChildModelAdmin):
    """ Base admin class for all child models """
    base_model = Publication  # Optional, explicitly set here.

@admin.register(Book)
class BookAdmin(PublicationChildAdmin):
    base_model = Book  # Explicitly set here!
#    show_in_index = True  # makes child model admin visible in main admin site
    list_display = ('title', 'publication_year', 'author_first', 'author_last')


@admin.register(Magazine)
class MagazineAdmin(PublicationChildAdmin):
    base_model = Magazine  # Explicitly set here!
#    show_in_index = True  # makes child model admin visible in main admin site
    list_display = ('title', 'publication_year', 'issue_name')


@admin.register(Publication)
class PublicationParentAdmin(PolymorphicParentModelAdmin):
    """ The parent model admin """
    base_model = Publication  # Optional, explicitly set here.
    child_models = (Book, Magazine)
    list_filter = (PolymorphicChildModelFilter,)  # This is optional.
    list_display = ('title', 'publication_year')

这当然只会显示那些常见的字段(在发布模型中)。如果您想显示每个模型特有的字段,则有各种技巧。这是一种快速的方法:

admin.py

...

@admin.register(Publication)
class PublicationParentAdmin(PolymorphicParentModelAdmin):
    """ The parent model admin """
    base_model = Publication  # Optional, explicitly set here.
    child_models = (Book, Magazine)
    list_filter = (PolymorphicChildModelFilter,)  # This is optional.
    list_display = ('title', 'publication_year', 'issue', 'author')
    def author(self, obj):
        if obj.polymorphic_ctype.model == 'book':
            book = Book.objects.get(pk=obj.pk)
            return book.author_first + ' ' + book.author_last
        return None

    def issue(self, obj):
        if obj.polymorphic_ctype.model == 'magazine':
            return str(Magazine.objects.get(pk=obj.pk).issue_name)
        return None

多田!

【讨论】:

以上是关于如何在 django admin 中显示多个模型的更改列表?的主要内容,如果未能解决你的问题,请参考以下文章

Django Admin Cookbook-8如何在Django admin中优化查询

在 Django Admin 中保存模型之前显示警报消息

应用程序(或模型)未显示在 Django Admin 中

Django Admin:如何在 oneToOne 关系中的两个模型中显示带有 list_display 的字段值?

如何从 django admin 添加多个客户地址

Django Admin Cookbook-39如何两次向Django管理员添加模型