django admin - list_filter 内的子查询

django admin - subquery inside 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)

和以下 admin.py 来自 django

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

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

如果我对你的问题的理解正确,你只想在你的 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 returns 给出过滤器值的元组列表
  • queryset 是实际过滤的内容。

然后你只需要将它添加到你的 OwnerAdmin 中,一切都会起作用:

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