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

时间:2019-06-05 07:32:37

标签: django django-admin django-1.10

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

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

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

2 个答案:

答案 0 :(得分:0)

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

因此,如果通常使用搜索,请构建一个特殊的模型/模型,以结合可能要搜索的数据

答案 1 :(得分:0)

如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

多田!

Publications listing showing Book and Magazine objects in one change list