“Django-filter”是否可以在ViewSet方法中使用FilterClass(FilterSet)MultipleChoiceFilter?Django 1.11,Python 2.7

50few1ms  于 2022-11-19  发布在  Go
关注(0)|答案(1)|浏览(114)

我有我的类ClassFilter(FilterSet)与一些过滤器fx. MultipleChoiceFilterModelMultipleChoiceFilter等在它:

class ClassFilter(FilterSet):
    something_severity = MultipleChoiceFilter(choices=Something.SEVERITY_CHOICES, method='something_severity_filter', widget=CSVWidget)

def something_severity_filter(self, queryset, name, severities):
    if severities:
        queryset = queryset.filter(something_state=Something.STATE_SOMETHING)
        ...
    return queryset

class Meta:
    model = Something
    fields = []

当涉及到过滤端点时,它工作得很完美。它被分配给如下类:

class ClassViewSet(mixins....., DefaultApiViewSet):
    filter_class = ClassFilter

通过有filter_class = ClassFilter。一切工作都很好,但现在我在怀疑,如果我可以使用ClassFilterMultipleChoiceFilterClassViewSet方法。
这意味着,通过在ClassViewSet中执行POST方法,我希望从FilterClass中获取MultipleChoiceFilter,以便通过将其作为SomethingFilter.get_filters()方法来过滤我的方法

@action(detail=False, methods=['post'])
def something_update(self, req):
...
all_filters = SomethingFilter.get_filters()

for serializer_filter in serializer_filters:
    for filter in all_filters:
        if(serializer_filter == filter):
            f = all_filters[filter]

现在f是我需要的一个过滤器,所以它是MultipleChoiceFilter但是当我尝试使用该过滤器进行过滤时,它抛出了一个错误。

f.filter(queryset, [('LOW')]) #filter the queryset with the filter based on LOW choice

掷回:

assertionError: Filter 'something_severity' must have a parent FilterSet to find '.something_severity_filter()'

django-filter文档中,它正好是行:https://github.com/carltongibson/django-filter/blob/f4866a9852d569861651cc733f909fe0e378131b/django_filters/filters.py#L823
所以我的观点是,如果有一种方法可以用ClassFilter来过滤这样的方法,如果有其他的方法可以正确地做,我打赌肯定有,这样我最终就不必做其他的过滤,保持低耦合。
如果有什么没有说清楚,让我补充这个问题!非常感谢你的每一个帮助。

g6ll5ycj

g6ll5ycj1#

所以我又回到了这个问题上,想出了一个解决办法。
当您在FilterSet类中设置了一些所需的筛选器(MultipleChoiceFilter等)时

class CarFilter(FilterSet):
    wheel = MultipleChoiceFilter(choices=Wheel.CHOICES, method='wheel_filter', widget=CSVWidget)

    def wheel_filter(self, queryset, name, cars):
        if cars:
            ...
        return queryset

    class Meta:
        model = Car
        fields = []

您必须在ViewSet中实现filter类:

class CarViewSet(DefaultApiViewSet):
    queryset = Car.objects.all()
    serializer_class = CarSerializer
    filter_class = CarFilter

您可以在ViewSet方法中使用您喜欢的过滤器,设置如下:

**重要提示!-**在上面的MultipleChoiceFilter中使用widget=CSVWidget时,其工作方式如下:

def car_method(self, req):
    queryset = self.filter_queryset(self.get_queryset())
    self.filter_class({"wheel": "MEDIUM,LOW"}, queryset).qs

当我们NOT使用widget=CSVWidget时,它的工作方式如下:

def car_method(self, req):
    queryset = self.filter_queryset(self.get_queryset())
    self.filter_class({'alert_severity': ['MEDIUM', 'LOW'], 'update_state': ['is_updated']}}, queryset).qs

完成了!我们根据车轮筛选汽车。

相关问题