是否可以制作一个django_filters.AllValuesFilter,其选择受给定查询集的约束

时间:2017-12-17 01:29:19

标签: django django-filter

我有一个像这样的模型:

class Worker(models.Model):
  city = models.CharField(max_length=50)

以下过滤器:

class CityFilter(django_filters.AllValuesFilter):

    @property
    def field(self):
        f = super(WorkerFilter, self).field
        f.choices = [('', '--------')] +  [(a.pk, a.city) for a in Worker.objects.all()]
        return f


class WorkerFilter(django_filters.FilterSet):
  city = ActuallyAllValuesFilter()
  class Meta:
    model = Worker
    fields = ['city']

我想创建一个AllValuesFilter但whit选项受制于给定的查询集而不是所有可能的值。我的意思是,我正在寻找类似的东西:

class CityFilter(django_filters.AllValuesFilter):

    @property
    def field(self, qs):
        f = super(WorkerFilter, self).field
        f.choices = [('', '--------')] +  [(a.pk, a.city) for a in qs]
        return f

有没有办法做到这一点?

1 个答案:

答案 0 :(得分:1)

您不清楚您期望使用哪个查询集,但我可以看到两种可能性:

1。使用提供给filterset的初始查询集。

class CityFilter(django_filters.ChoiceFilter):

    @property
    def field(self):
        self.extra['choices'] = [(a.city, a.city) for a in self.parent.queryset]
        return super(CityFilter, self).field

class WorkerFilter(django_filters.FilterSet):
    city = CityFilter(field_name='city')

    class Meta:
        model = Worker
        fields = ['city']

请注意,过滤器实例化后,过滤器可以访问其parent过滤器。 self.parent.queryset是提供给filterset的初始查询集。

此外,在这种情况下,您没有必要使用AllValuesFilter,因为您正在放弃它生成的选项。继承自ChoiceFilter

2。为过滤器实例提供查询集。

class CityFilter(django_filters.ChoiceFilter):

    def __init__(self, *args, queryset, **kwargs):
        workers = kwargs.pop('workers', None)

        kwargs['choices'] = [(a.city, a.city) for a in workers]
        super(CityFilter, self).__init__(*args, **kwargs)

class WorkerFilter(django_filters.FilterSet):
    city = CityFilter(field_name='city', workers=Worker.objects.filter(...))

    class Meta:
        model = Worker
        fields = ['city']