简体   繁体   English

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

[英]Filtering list_filter in Django admin based on field in foreign key

I would like to filter one of my list_filters by a field in the table that the foreign key points to.我想通过外键指向的表中的字段过滤我的 list_filters 之一。

My models:我的模型:

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)

I would like to put in IssueAdmin:我想放入 IssueAdmin:

list_filter = (charity)

And for that to supply a list of charities.并为此提供一份慈善机构名单。 Currently it just lists everything in the organisation model, both the charities and the companies.目前它只列出组织模型中的所有内容,包括慈善机构和公司。 For example I get this list in the filter at the moment:例如,我现在在过滤器中得到这个列表:

oxfam
yamaha
greenpeace
microsoft

When I want a filter that lists:当我想要一个列出的过滤器时:

oxfam
greenpeace

I could fix this by splitting the organisation table into two tables (charity and company) but that feels wrong.我可以通过将组织表分成两个表(慈善机构和公司)来解决这个问题,但这感觉不对。

It seems like SimpleListFilter should work, but I've not had any luck so far.看起来 SimpleListFilter 应该可以工作,但到目前为止我还没有运气。 Basically I would like something the uses the following filter and returns a list of charities for the filter:基本上我想要一些使用以下过滤器并返回过滤器的慈善机构列表的东西:

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

My (poor) attempt at a filter:我的(可怜的)过滤器尝试:

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

Can any one help me?任何人都可以帮助我吗?

Why don't you just filter on the type, ie:为什么不只过滤类型,即:

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

It would allow you to have either all organisations, companies only or charities only.它将允许您拥有所有组织、仅公司或仅慈善机构。

Else if you realy want to treat "Charities" and "Companies" as distinct entities with distinct admins but still keep them in the same table, you can use proxy models, but I don't see the point here.否则,如果您真的想将“慈善机构”和“公司”视为具有不同管理员的不同实体,但仍将它们保留在同一个表中,则可以使用代理模型,但我不明白这里的意义。

Edit : to filter issues based on organization type it works just the same as with querying on relayed models (not a surprise since it's exactly what happens)编辑:根据组织类型过滤issues ,它的工作原理与在中继模型上查询相同(并不奇怪,因为这正是发生的事情)

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

If I'm getting it right you're trying to filter Issue instances not by the type of the Organization they belong to, but by the Organization instances themselves, so you will have on the right a potentially very long list of Organizations to filter Issues on, but you want only CHARITies to appear in this list.如果我做对了,您不是根据它们所属的组织类型,而是根据组织实例本身来过滤问题实例,因此您将在右侧有一个可能很长的组织列表来过滤问题上,但您只希望 CHARITies 出现在此列表中。

This may not be the best solution if there are many Organizations, but only if they're few...如果有很多组织,这可能不是最好的解决方案,但前提是它们很少......

Anyway, as per the Django docs: https://docs.djangoproject.com/en/dev/ref/contrib/admin/ the lookups() method of a Filter must return a list of tuple (coded_value,displayed_value).无论如何,根据 Django 文档: https ://docs.djangoproject.com/en/dev/ref/contrib/admin/ 过滤器的 lookups() 方法必须返回一个元组列表 (coded_value,displayed_value)。

The following untested code should work in your case:以下未经测试的代码应该适用于您的情况:

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())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM