Django Rest Framework (фильтр GET в поле ManyToMany)

Я пытаюсь понять, как фильтровать поле ManyToMany по значению. В Django это так же просто, как queryset.filter(m2mfield__name), но я не могу понять, чего мне не хватает. Я использую Django Rest Framework и DjangoFilterBackend.

Модели:

class City(models.Model):
    name = models.CharField(max_length=80)

class State(models.Model):
    name = models.CharField(max_length=50)
    cities = models.ManyToManyField(City)

Фильтры:

import django_filters

class StateFilter(django_filters.FilterSet):
    cities = django_filters.CharFilter(
        name='cities__name',
        lookup_type='contains',
    )

    class Meta:
        model = State
        fields = ('name', 'cities')

Сериализаторы:

class CitySerializer(serializers.ModelSerializer):
    class Meta:
        model = City
        fields = ('name', )

class StateSerializer(serializers.ModelSerializer):
    cities = CitySerializer(many=True)

    class Meta:
        model = State
        fields = ('name', 'cities')
        filter_class = StateFilter

Просмотр:

from rest_framework.generics import ListAPIView, RetrieveAPIView
from .serializers import StateSerializer

class StateList(ListAPIView):
    queryset = State.objects.all()
    serializer_class = StateSerializer
    filter_fields = ('name', 'cities')

Вывод для ../api/states/ в настоящее время:

 [
     "name": "Florida",
     "cities": [
          "name": "Tampa",
          "name": "St. Petersburg",
          "name": "Orlando"
     ],
     "name": "North Carolina",
     "cities": [
          "name": "Raleigh",
          "name": "Charlotte",
          "name": "Greensboro"
     ]
 ]

Как я могу отфильтровать города с помощью вызова GET по имени, например:

../api/states/?cities=Шарлотта

Результат вышеизложенного должен быть:

 [
     "name": "North Carolina",
     "cities": [
          "name": "Raleigh",
          "name": "Charlotte",
          "name": "Greensboro"
     ]
 ]

person Michael B    schedule 19.09.2014    source источник
comment
Можете ли вы показать свой ViewSet?   -  person Zulu    schedule 20.09.2014
comment
@Zulu, я добавил ViewSet по запросу.   -  person Michael B    schedule 20.09.2014
comment
REST_FRAMEWORK = { 'FILTER_BACKEND': 'rest_framework.filters.DjangoFilterBackend', }   -  person Michael B    schedule 20.09.2014


Ответы (1)


Ну, я понял, что я делал неправильно. Это было на виду. Я не объявлял filter_class в представлении:

from rest_framework.generics import ListAPIView, RetrieveAPIView
from .serializers import StateSerializer
from .filters import StateFilter

class StateList(ListAPIView):
    queryset = State.objects.all()
    serializer_class = StateSerializer
    filter_fields = ('name', 'cities')
    filter_class = StateFilter  # This was missing

Вместо этого я случайно поместил его в сериализатор.

person Michael B    schedule 19.09.2014