Django admin 查询集通过外键向后关系过滤

Posted

技术标签:

【中文标题】Django admin 查询集通过外键向后关系过滤【英文标题】:Django admin queryset filtering by foreign key backwards relation 【发布时间】:2012-11-18 16:15:00 【问题描述】:

我有模型 A 和 B,其中 B 对 A 有 FK。

我使用 django 1.3,我需要两个 django 管理过滤器:

1) a.b_set.exists() # (True/False)

2) not a.b_set.filter(some_condition=False).exists() # (True/False)

我怎样才能做到这一点?可悲的是,我无法通过谷歌搜索找到任何解决方案。

【问题讨论】:

A.objects.filter(b__isnull=False)A.objects.filter(b__isnull=False, some_condition=False) 有帮助吗? 也许吧,但我问的是如何编写自定义 display_filter,而不是如何进行查询。 升级到 Django 1.4 是否是一种选择?列表过滤器在那里变得更加灵活。您基本上可以指定自己的列表过滤器类:docs.djangoproject.com/en/1.4/ref/contrib/admin/… 嗯,目前无法升级,但 1.4 的灵活性看起来不错。 【参考方案1】:

@ptrck 提到的是正确的。你不能切换到 1.4 吗?

在这种情况下,如the doc 所述,无需更改查找,执行类似的操作(此处为第一个,然后相应地为第二个):

from django.contrib.admin import BooleanFieldListFilter

class BInA(BooleanFieldListFilter):
    def queryset(self, request, queryset):
        if self.value() is True:
            return queryset.filter(a.b_set.exists())
        else:
            return queryset.filter(a.b_set.exists() is False)

【讨论】:

【参考方案2】:

您需要阅读以下内容:Custom Filter in Django Admin on Django 1.3 or below

这是我第一次尝试没有任何测试,但你应该或多或少看到它是如何完成的 -

from django.db import models
from django.contrib.admin.filterspecs import FilterSpec, ChoicesFilterSpec
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext as _

class BNullSetFilterSpec(FilterSpec):

    def __init__(self, f, request, params, model, model_admin):
        super(BSetFilterSpec, self).__init__(f, request, params, model, model_admin)

        self.links = (
            ('Yes', 'b__isnull': False),
            ('No', ))

    def title(self):
        return _('B Set')

# registering the filter
FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'empty_bset', False), BNullSetFilterSpec))

【讨论】:

以上是关于Django admin 查询集通过外键向后关系过滤的主要内容,如果未能解决你的问题,请参考以下文章

Django 查询集外键

如何使用Django中的外键关系中的任何/ exists / all逻辑检索查询集?

按外键/相关字段分组 django 查询集

告诉django不要跟随外键?

如何通过django中的多级反向外键获取相关对象查询集?

Django 将带有外键的查询集转换为 JSON