" Django-filter " Возможно ли использовать FilterClass(FilterSet) MultipleChoiceFilter внутри методов ViewSet? Django 1.11, Python 2.7

У меня есть мой класс ClassFilter(FilterSet) с некоторыми Filters fx. MultipleChoiceFilter, ModelMultipleChoiceFilter и т.д. в нем:

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. Все работает просто отлично, но теперь я сомневаюсь, могу ли я использовать ClassFilter MultipleChoiceFilter внутри ClassViewSet методов.

Это означает, что выполняя POST метод в ClassViewSet, я хочу получить MultipleChoiceFilter из FilterClass для фильтрации моего метода, получив его как 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 как у меня. Если есть какой-то другой способ, как на самом деле сделать это правильно. Я уверен, что есть, так что в конечном итоге мне не придется делать другую фильтрацию и сохранять низкую связь.

Если есть что-то, что не ясно сказано, позвольте мне добавить к этому вопросу! Большое спасибо за любую помощь.

Так что я вернулся к проблеме и придумал решение.

Когда вы установили некоторые нужные вам фильтры в классе 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 = []

Вам необходимо реализовать класс filter в ViewSet:

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

Вы можете использоватьфильтр по своему усмотрению в методах ViewSet, если зададите его следующим образом:

ВАЖНО! - При использовании widget=CSVWidget в MultipleChoiceFilter выше, это работает следующим образом:

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

Когда мы НЕ используем 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

Закончено! Мы отфильтровали автомобили на основе их колес.

Вернуться на верх