Django REST框架外键和过滤

dea*_*ase 15 python django rest django-models 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]
Run Code Online (Sandbox Code Playgroud)

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')
Run Code Online (Sandbox Code Playgroud)

还有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,)
Run Code Online (Sandbox Code Playgroud)

我需要做什么,我想获取特定品牌生产的所有型号.如何使用查询参数获取具有特定make外键的所有模型?我的第二个问题 - 我可以使用queryparams过滤结果以获得具有特定engine_capacity的模型吗?

一条评论:如果我能在url中使用类似的东西查询结果,那将是完美的:/api/models/?make=ford其中make是模型中的slug字段Make

Vla*_*kov 29

您可以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',)
Run Code Online (Sandbox Code Playgroud)

然后你查询喜欢/api/models/?make__slug=ford.注意双下划线符号.

文件.

如果您不喜欢make__slugURL中的关键字参数,则可以创建过滤器类:

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',)
Run Code Online (Sandbox Code Playgroud)

然后

class ModelViewSet(viewsets.ModelViewSet):
    make = MakeSerializer
    queryset = Model.objects.all()
    serializer_class = ModelSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filter_class = ModelFilter
Run Code Online (Sandbox Code Playgroud)

/api/models/?make=ford 应该管用.

  • 这认为这是最好的答案:P (6认同)

dan*_*eia 9

urls.py

url('^model/by/(?P<make>\w+)/$', ModelByMakerList.as_view()),
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请查看文档.

你也可以使用QUERY_PARAMS过滤,但恕我直言这看起来更好.