是否可以使用受给定查询集约束的选择来制作 django_filters.AllValuesFilter

Is it possible to make a django_filters.AllValuesFilter with choices subject to a given queryset

我有这样一个模型:

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,但选择受制于给定的查询集而不是所有可能的值。我的意思是,我正在寻找类似的东西:

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。使用提供给过滤器集的初始查询集。

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 是提供给过滤器集的初始 查询集。

此外,在这种情况下没有必要使用 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']