【问题标题】:How to filter the values of two fields as one?如何将两个字段的值过滤为一个?
【发布时间】:2014-11-25 20:07:56
【问题描述】:

如何在django-filter中聚合两个字段的结果并显示为一个?

我们以这样的模型为例:

class Animal(object):
     LEGS_CHOICES = (2, 4, 8)
     legs = models.PositiveSmallIntegerField(choices=LEGS_CHOICES)

class Dog(Animal):
     pass

class Spider(Animal):
     pass

我的 django-filter 过滤器类:

class AnimalFilterSet(django_filters.FilterSet):
    legs = django_filters.MultipleChoiceFilter(choices=Animal.LEGS_CHOICES, widget=forms.CheckboxSelectMultiple())

    class Meta:
        model = Animal
        fields = ['legs']

我想通过相同的字段过滤这两个模型并将它们显示为一个。

使用查询集我可以这样做:

Animal.objects.filter(Q(dog__legs = 4) | Q(spider__legs = 4))

【问题讨论】:

    标签: django-filter


    【解决方案1】:

    我写了自己的过滤器

    class MultiMultipleChoiceFilter(django_filters.Filter):
        """
        This filter preforms an OR query on the selected options for defined fields.
        """
        field_class = forms.MultipleChoiceField
    
        def __init__(self, fields, *args, **kwargs):
            super(MultiMultipleChoiceFilter, self).__init__(*args, **kwargs)
            self.fields = fields
    
        def filter(self, qs, value):
            value = value or ()
            if len(value) == len(self.field.choices):
                return qs
            q = Q()
            for v in value:
                for f in self.fields:
                    q |= Q(**{f: v})
            return qs.filter(q).distinct()
    

    使用示例。作为参数,输入字段列表。

    class AnimalFilterSet(django_filters.FilterSet):
        legs = django_filters.MultiMultipleChoiceFilter(['dog__legs', 'spider__legs'], choices=Animal.LEGS_CHOICES, widget=forms.CheckboxSelectMultiple())
    
        class Meta:
            model = Animal
            fields = ['legs']
    

    【讨论】:

    • 这对我帮助很大,谢谢。但是,在 django-filter v.1.0.4 中,表单标签在页面上呈现为 [invalid field],除非我在 FilterSet 类中的字段 def 中包含显式的“标签”选项。
    猜你喜欢
    • 2020-03-21
    • 1970-01-01
    • 2018-01-27
    • 2022-08-15
    • 2021-07-06
    • 1970-01-01
    • 2019-01-29
    • 2021-12-30
    • 1970-01-01
    相关资源
    最近更新 更多