簡體   English   中英

Django REST 框架外鍵和過濾

[英]Django REST framework foreign keys and filtering

我在 Django 應用中有以下模型:

模型.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 外鍵的所有模型? 我的第二個問題 - 我可以使用 queryparams 過濾結果以獲得具有特定引擎容量的模型嗎?

一條評論:如果我可以在 url: /api/models/?make=ford中使用類似這樣的內容查詢結果,那就太完美了,其中makeMake模型中的slug字段

您可以在視圖集中指定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這樣的查詢。 注意雙下划線符號。

文檔

如果你不喜歡 URL 中的make__slug關鍵字參數,那么你可以創建一個過濾器類:

import django_filters

from myapp.models import Make


class ModelFilter(django_filters.FilterSet):
    make = django_filters.ModelChoiceFilter(field_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應該可以工作。

網址.py

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

視圖.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 過濾,但恕我直言,這看起來更好。

要擴展@vladimir-prudnikov 的回答

在 django-filter 的最新版本中,事情發生了一些變化。 你可能想要:

class ModelFilter(django_filters.FilterSet):
    make = django_filters.ModelChoiceFilter(field_name='make__slug',
                                            to_field_name='slug',
                                            queryset=Make.objects.all())

    class Meta:
        model = Model
        fields = ('make',)

請參閱https://django-filter.readthedocs.io/en/master/ref/filters.html#field-namehttps://django-filter.readthedocs.io/en/master/ref/filters.html#to -字段名稱

在您看來,您需要做的事情是這樣的:它被稱為“跨越關系的查找”

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 查詢制作

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM