Внешние ключи и фильтрация Django Rest framework
у меня есть следующие модели в приложении django:
models.py:
class Make(BaseModel):
slug = models.CharField(max_length=32) #alfa-romeo
name = models.CharField(max_length=32) #Alfa Romeo
def __unicode__(self):
return self.name
class Model(BaseModel):
make = models.ForeignKey(Make) #Alfa Romeo
name = models.CharField(max_length=64) # line[2]
engine_capacity = models.IntegerField()
trim = models.CharField(max_length=128) # line[4]
и serializers.py:
from .models import Make,Model
from rest_framework import serializers
class MakeSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Make
fields = ('url', 'slug', 'name')
class ModelSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Model
fields = ('url', 'make', 'name', 'trim', 'engine_capacity')
и views.py:
from rest_framework import viewsets
from rest_framework import filters
from rest_framework import generics
from .models import Make, Model
from .serializers import MakeSerializer, ModelSerializer
class MakeViewSet(viewsets.ModelViewSet):
queryset = Make.objects.all()
serializer_class = MakeSerializer
filter_backends = (filters.DjangoFilterBackend,)
class ModelViewSet(viewsets.ModelViewSet):
make = MakeSerializer
queryset = Model.objects.all()
serializer_class = ModelSerializer
filter_backends = (filters.DjangoFilterBackend,)
что мне нужно, я хочу получить все модели, изготовленные конкретной маркой. Как я могу получить все модели с определенным внешним ключом make, используя параметры запроса? И мой 2-й вопрос-Могу ли я фильтровать результаты с помощью queryparams для получения моделей с конкретными engine_capacity?
один комментарий: было бы идеально, если бы я мог запросить результаты, используя что-то вроде этого в url: /api/models/?make=ford
здесь сделать и
3 ответов
urls.py
url('^model/by/(?P<make>\w+)/$', ModelByMakerList.as_view()),
views.py
class ModelByMakerList(generics.ListAPIView):
serializer_class = ModelSerializer
def get_queryset(self):
"""
This view should return a list of all models by
the maker passed in the URL
"""
maker = self.kwargs['make']
return Model.objects.filter(make=maker)
дополнительная информация проверка документов.
вы также можете использовать фильтрацию с QUERY_PARAMS, но IMHO это выглядит лучше.
вы можете указать filter_fields = ('make__slug', )
в вашем наборе представлений. Не забудьте включить filter_backends = (DjangoFilterBackend, )
как хорошо. Также вам нужно будет добавить django-filter
зависимость.
class ModelViewSet(viewsets.ModelViewSet):
queryset = Model.objects.all()
serializer_class = ModelSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('make__slug',)
затем вы запрос /api/models/?make__slug=ford
. Двойной символ подчеркивания.
Docs.
Если вам не нравится make__slug
аргумент ключевого слова в URL, то вы можете создать класс фильтра:
import django_filters
from myapp.models import Make
class ModelFilter(django_filters.FilterSet):
make = django_filters.ModelChoiceFilter(name="make__slug",
queryset=Make.objects.all())
class Meta:
model = Model
fields = ('make',)
а то
class ModelViewSet(viewsets.ModelViewSet):
make = MakeSerializer
queryset = Model.objects.all()
serializer_class = ModelSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_class = ModelFilter
/api/models/?make=ford
должны работать.
что вам нужно сделать, по вашему мнению, что-то вроде этого: Это называется "Поиск, который охватывает отношения"
queryset = Model.objects.filter(make__name__exact='Alfa Romeo')
фильтрация моделей с определенной мощностью двигателя аналогична
queryset = Model.objects.filter(engine_capacity__exact=5)
Если вы хотите объединить оба фильтра, вы можете связать их:
queryset = Model.objects.filter(make__name__exact='Alfa Romeo').filter(engine_capacity__exact=5)
больше примеров можно найти здесь создание запросов django