根据外键中的字段过滤Django admin中的list_filter

时间:2013-11-22 16:06:36

标签: django django-admin

我想通过外键指向的表中的字段过滤我的list_filters之一。

我的模特:

class Organisation(models.Model):
    name = models.CharField()
    COMPANY = 'COMPANY'
    CHARITY = 'CHARITY'
    ORG_CHOICES = (
        (COMPANY, 'COMPANY'),
        (CHARITY, 'CHARITY'),
        )
    type = models.CharField(choices = ORG_CHOICES)

class Issue(models.Model):
   name = models.CharField
   charity = models.ForeignKey(Organisation)

我想放入IssueAdmin:

list_filter = (charity)

为此提供慈善机构清单。目前,它只列出了组织模型中的所有内容,包括慈善机构和公司。例如,我现在在过滤器中得到这个列表:

oxfam
yamaha
greenpeace
microsoft

当我想要一个列出的过滤器时:

oxfam
greenpeace

我可以通过将组织表分成两个表(慈善机构和公司)来解决这个问题,但这感觉不对。

似乎SimpleListFilter应该可以工作,但到目前为止我还没有运气。基本上我想要使用以下过滤器并返回过滤器的慈善机构列表:

Organisation.objects.filter(type = 'CHARITY')

我(差)尝试过滤器:

class CharityFilter(SimpleListFilter):
    title = _('Charity')
    parameter = _('charity__type')
    def lookups(self, request, model_admin):
        return Organisation.objects.filter(type = 'CHARITY')

    def queryset(self, request, queryset):
        if not self.value() is not None:
            return queryset.filter(type = 'CHARITY')
        else:
            return queryset

任何人都可以帮助我吗?

2 个答案:

答案 0 :(得分:5)

为什么不直接过滤类型,即:

class OrganisationAdmin(admin.ModelAdmin):
    list_filter = ("type", )
    # etc

它允许您拥有所有组织,仅限公司或慈善机构。

否则,如果您真的希望将“慈善机构”和“公司”视为具有不同管理员的不同实体,但仍将它们保存在同一个表中,则可以使用代理模型,但我不明白这一点。

编辑:根据组织类型过滤问题,它与在中继模型上查询的工作方式相同(这不是一个惊喜,因为它正是发生的事情)

class IssueAdmin(admin.ModelAdmin):
    list_filter =("organisation__type", )

答案 1 :(得分:4)

如果我做得对,你试图过滤问题实例而不是它们所属的组织类型,而是通过组织实例本身,所以你将在右边有一个可能很长的组织列表过滤问题,但您只希望CHARIT出现在此列表中。

如果有很多组织,这可能不是最好的解决方案,但只有少数组织......

无论如何,根据Django文档:https://docs.djangoproject.com/en/dev/ref/contrib/admin/,Filter的lookups()方法必须返回一个元组列表(coded_value,displayed_value)。

以下未经测试的代码应该适用于您的情况:

class CharityFilter(SimpleListFilter):
    title = _('Charity')
    parameter_name = 'charity'
    def lookups(self, request, model_admin):
        queryset = model_admin.queryset(request).filter(organisation__type='CHARITY')
        return queryset.values_list('organisation__pk','organisation__name').order_by('organisation__name')

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