そこで、RESTフレームワークを使用して「API」を作成しました。現在、それをフィルタリングしようとしています。それが私のmodels.py
多かれ少なかれのように見える:
class Airline(models.Model):
name = models.TextField()
class Workspace(models.Model):
airline = models.ForeignKey(Airline)
name = models.CharField(max_length=100)
class Passenger(models.Model):
workspace = models.ForeignKey(Workspace)
title = models.CharField(max_length=200)
だから、JSONファイルで「特定のワークスペースのすべての乗客」または「特定の航空会社のすべての乗客」などを見たいと思います。
これが私の、serializers.py
class AirlineSerializer(serializers.ModelSerializer):
class Meta:
model = Airline
class WorkspaceSerializer(serializers.ModelSerializer):
class Meta:
model = Workspace
class PassengerSerializer(serializers.ModelSerializer):
class Meta:
model = Passenger
そしてviews.py
:
class AirlineList(generics.ListCreateAPIView):
model = Airline
serializer_class = AirlineSerializer
class AirlineDetail(generics.RetrieveUpdateDestroyAPIView):
model = Airline
serializer_class = AirlineSerializer
class WorkspaceList(generics.ListCreateAPIView):
model = Workspace
serializer_class = WorkspaceSerializer
class WorkspaceDetail(generics.RetrieveUpdateDestroyAPIView):
model = Workspace
serializer_class = WorkspaceSerializer
class PassengerList(generics.ListCreateAPIView):
model = Passenger
serializer_class = PassengerSerializer
class PassengerDetail(generics.RetrieveUpdateDestroyAPIView):
model = Passenger
serializer_class = PassengerSerializer
RESTフレームワークを使用するのは初めてです。ドキュメントを確認しました。これまで行ってきたことを助けてくれました。
クエリパラメータに対するフィルタリング: http://www.Django-rest-framework.org/api-guide/filtering/#filtering-against-query-parameters
本当に得られない..
@limelightsを使用して、私がやりたいことをなんとかして、コードを以下に示します。
class PassengerList(generics.ListCreateAPIView):
model = Passenger
serializer_class = PassengerSerializer
# Show all of the PASSENGERS in particular WORKSPACE
# or all of the PASSENGERS in particular AIRLINE
def get_queryset(self):
queryset = Passenger.objects.all()
workspace = self.request.query_params.get('workspace')
airline = self.request.query_params.get('airline')
if workspace:
queryset = queryset.filter(workspace_id=workspace)
Elif airline:
queryset = queryset.filter(workspace__airline_id=airline)
return queryset
Docs http://www.Django-rest-framework.org/api-guide/filtering/#djangofilterbackend に記載されているDjango-filterパッケージを使用するだけで、同じ機能をすぐに使用できます=
from rest_framework import filters
class PassengerList(generics.ListCreateAPIView):
model = Passenger
serializer_class = PassengerSerializer
queryset = Passenger.objects.all()
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('workspace', 'workspace__airline')
この場合、「workspace = 1」または「workspace__airline = 1」を使用してフィルタリングする必要があります
この Djangoアプリ は、着信クエリパラメーターを使用して、クリーンでエレガントな方法でビューのクエリセットにフィルターを適用します。
pip install drf-url-filters
としてpipでインストールできます
使用例
validations.py
from filters.schema import base_query_param_schema
from filters.validations import (
CSVofIntegers,
IntegerLike,
DatetimeWithTZ
)
# make a validation schema for players filter query params
players_query_schema = base_query_param_schema.extend(
{
"id": IntegerLike(),
"name": unicode,
"team_id": CSVofIntegers(), # /?team_id=1,2,3
"install_ts": DatetimeWithTZ(),
"update_ts": DatetimeWithTZ(),
}
)
views.py
from rest_framework import (
viewsets,
filters,
)
from .models import Player, Team
from .serializers import PlayerSerializer, TeamSerializer
from .pagination import ResultSetPagination
from .validations import teams_query_schema, players_query_schema
from filters.mixins import (
FiltersMixin,
)
class PlayersViewSet(FiltersMixin, viewsets.ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
"""
serializer_class = PlayerSerializer
pagination_class = ResultSetPagination
filter_backends = (filters.OrderingFilter,)
ordering_fields = ('id', 'name', 'update_ts')
ordering = ('id',)
# add a mapping of query_params to db_columns(queries)
filter_mappings = {
'id': 'id',
'name': 'name__icontains',
'team_id': 'teams', # many-to-many relationship
'install_ts': 'install_ts',
'update_ts': 'update_ts',
'update_ts__gte': 'update_ts__gte',
'update_ts__lte': 'update_ts__lte',
}
# add validation on filters
filter_validation_schema = players_query_schema
def get_queryset(self):
"""
Optionally restricts the queryset by filtering against
query parameters in the URL.
"""
query_params = self.request.query_params
queryset = Player.objects.prefetch_related(
'teams' # use prefetch_related to minimize db hits.
).all()
# This dict will hold filter kwargs to pass in to Django ORM calls.
db_filters = {}
# update filters dict with incoming query params and then pass as
# **kwargs to queryset.filter()
db_filters.update(
self.get_queryset_filters(
query_params
)
)
return queryset.filter(**db_filters)