【问题标题】:Django filters - Using an AllValuesFilter (with a LinkWidget) on a ManyToManyFieldDjango 过滤器 - 在 ManyToManyField 上使用 AllValuesFilter(带有 LinkWidget)
【发布时间】:2011-01-08 12:15:59
【问题描述】:

这是我的第一个 Stack Overflow 问题,如果我做错了什么,请告诉我。

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

很遗憾,如果我以标准方式尝试此操作,则会收到错误消息(无效的字段名称:'operator'):

# 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 的新手。有人能想出一种更通用/优雅的方式吗?

【问题讨论】:

    标签: django django-filter


    【解决方案1】:

    为什么要继承 LinkOrderFilterSet?

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

    import django_filters 
    
    class SignFilter(django_filters.FilterSet):  
        operator = django_filters.AllValuesFilter(widget=django_filters.widgets.LinkWidget)  
    
        class Meta:
            model = Sign
            fields = ['operator']
    

    【讨论】:

      【解决方案2】:

      你可以用这个

      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']
      

      【讨论】:

        猜你喜欢
        • 2022-11-25
        • 2020-02-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-12
        • 2020-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多