Django app:に次のモデルがあります。
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を持つモデルを取得できますか?
1つのコメント:URLで次のようなものを使用して結果をクエリできる場合は完璧です:/api/models/?make=ford
ここで、makeはslug
モデルのMake
フィールドです
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でフィルタリングを使用することもできますが、私見ではこれの方が見栄えがします。
ビューセットで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(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クエリ作成
@ vladimir-prudnikovの answer を拡張するには:
最近のバージョンの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-name および https://Django-filter.readthedocs.io/ en/master/ref/filters.html#to-field-name