如何将两个字段的值过滤为一个?

时间:2014-11-25 20:07:57

标签: django-filter

如何聚合两个字段的结果并在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']

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

使用queryset我可以这样做:

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

1 个答案:

答案 0 :(得分: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']