首页 > 解决方案 > django admin - list_filter 中的子查询

问题描述

给出了以下模型

class Report(models.Model):
    id = models.CharField(max_length=256, unique=True)
    name = models.CharField(max_length=256)
    confidential = models.BooleanField(default=False)

class Owner(models.Model):
    first_name = models.CharField(max_length=512)
    last_name = models.CharField(max_length=512)
    title = models.CharField(max_length=512)
    birth_date = models.CharField(max_length=512)
    company = models.CharField(max_length=512)
    address = models.CharField(max_length=512)
    city = models.CharField(max_length=512)
    last_login = models.DateTimeField(auto_now=True)
    access_granted = models.DateTimeField(auto_now_add=True)
    report = models.ForeignKey(Report, on_delete=models.CASCADE)

以及来自 django 的以下 admin.py

class OwnerAdmin(admin.ModelAdmin):
    .
    .
    .
    list_filter = ('report__name',)

正如预期的那样,我可以选择根据报告的名称进行过滤。然而,如果报告是机密的,我只想显示过滤器,这意味着confidential给定报告的字段是真实的。我怎样才能做到这一点?

标签: pythondjangodjango-adminweb-development-serverdjango-admin-filters

解决方案


如果我正确理解您的问题,您只想在 list_filter 中列出机密报告。为此,您需要创建一个自定义过滤器:

class ReportListFilter(admin.SimpleListFilter):

    title = 'Confidential Reports'
    parameter_name = 'confidential_reports'

    def lookups(self, request, model_admin):
        confidential_reports = Report.objects.filter(confidential=True)
        return tuple(
            (report.id, report.name) for report in confidential_reports
        )

    def queryset(self, request, queryset):
        if self.value()
            return queryset.filter(report_id=self.value())
        return queryset.all()

要理解上述内容,您可以在docs中阅读更多相关信息,但总结如下:

  • title: 给出过滤器的标题
  • parameter_name: 给出使用过滤器时将在 URL 中使用的字符串
  • lookups返回给出过滤器值的元组列表
  • queryset是什么实际过滤。

然后你只需要将它添加到你的OwnerAdmin,一切都应该工作:

class OwnerAdmin(admin.ModelAdmin):
    .
    .
    .
    list_filter = (ReportListFilter,)

推荐阅读