2010-01-23 117 views
1

这是我的第一个堆栈溢出问题,所以请让我知道如果我做错了什么。Django过滤器 - 在ManyToManyField上使用AllValuesFilter(使用LinkWidget)

我希望使用美妙的django-filters应用程序在ManyToMany字段上创建一个AllValues过滤器。基本上,我想创建一个看起来像Admin中的过滤器,所以我也想使用LinkWidget。

不幸的是,我得到一个错误(无效的字段名称:“经营者”),如果我尝试这种标准方式:

# Models 
class Organisation(models.Model): 
    name = models.CharField() 
    ... 

class Sign(models.Model): 
    name = models.CharField() 
    operator = models.ManyToManyField('Organisation', blank=True) 
    ... 

# Filter 
class SignFilter(LinkOrderFilterSet): 
    operator = django_filters.AllValuesFilter(widget=django_filters.widgets.LinkWidget) 

    class Meta: 
     model = Sign 
     fields = ['operator'] 

我身边这让通过创建我自己的很多过滤器,以一对多的关系硬编码:

# Models 
class Organisation(models.Model): 
    name = models.CharField() 
    ... 

class Sign(models.Model): 
    name = models.CharField() 
    operator = models.ManyToManyField('Organisation', blank=True) 
    ... 

# Filter 
class MyFilter(django_filters.ChoiceFilter): 
    @property 
    def field(self): 
     cd = {} 
     for row in self.model.objects.all(): 
      orgs = row.operator.select_related().values() 
     for org in orgs: 
      cd[org['id']] = org['name']  
     choices = zip(cd.keys(), cd.values()) 
     list.sort(choices, key=lambda x:(x[1], x[0])) 
     self.extra['choices'] = choices 
     return super(AllValuesFilter, self).field 

class SignFilter(LinkOrderFilterSet): 
    operator = MyFilter(widget=django_filters.widgets.LinkWidget) 

我是Python和Django的新手。有人可以想到一个更通用/优雅的方式吗?

回答

0

你为什么继承LinkOrderFilterSet?

也许使用它的连接方式是这样的:

import django_filters 

class SignFilter(django_filters.FilterSet): 
    operator = django_filters.AllValuesFilter(widget=django_filters.widgets.LinkWidget) 

    class Meta: 
     model = Sign 
     fields = ['operator'] 
1

您可以使用此

class CircleFilter(django_filters.FilterSet): 
    l = [] 
    for c in Organisation.objects.all(): 
     l.append((c.id, c.name)) 
    operator = django_filters.ChoiceFilter(
     choices=set(l)) 

class Meta: 
    model = Sign 
    fields = ['operator']