web-dev-qa-db-ja.com

Django REST FrameworkでカスタムJSONを返す方法

get_querysetでカスタムjsonを返そうとしていますが、常に応答で404 errorを取得します。

class TestViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Test.objects.all()
    serializer_class = TestSerializer

    def get_queryset(self):
        if self.request.method == "GET":
            content = {'user_count': '2'}
            return HttpResponse(json.dumps(content), content_type='application/json')

defから始まるすべてを削除すると、標準のjsonデータで正しい応答が得られます。私が間違っているのは何ですか?

35
Roberto

ModelViewSetが不要で、GETリクエストでカスタムJSONが必要な場合

また、モデルを必要としない APIView を使用することもできます

class MyOwnView(APIView):
    def get(self, request):
        return Response({'some': 'data'})

そして

urlpatterns = [
    url(r'^my-own-view/$', MyOwnView.as_view()),
]

ModelViewSetを使用

カスタムJSONをget_querysetに入れましたが、それは間違っています。 ModelViewSetを使用する場合は、これだけで十分です。

class TestViewSet(viewsets.ModelViewSet):
    queryset = Test.objects.all()
    serializer_class = TestSerializer

このModelViewSetには、.list().retrieve().create().update()、および.destroy()のデフォルト実装が付属しています。必要に応じてオーバーライド(カスタマイズ)できるもの

ModelViewSet.retrieve()または.list()からカスタムJSONを返す

例えば。 .retrieve()をオーバーライドして、単一のオブジェクトを取得するときにカスタムビューを返します。 デフォルトの実装は次のようになります を見ることができます:

def retrieve(self, request, *args, **kwargs):
    instance = self.get_object()
    serializer = self.get_serializer(instance)
    return Response(serializer.data)

カスタムJSONを返す例として:

class TestViewSet(viewsets.ModelViewSet):
    queryset = Test.objects.all()
    serializer_class = TestSerializer

    def retrieve(self, request, *args, **kwargs):
        return Response({'something': 'my custom JSON'})

    def list(self, request, *args, **kwargs):
        return Response({'something': 'my custom JSON'})
55
bakkal

ModelViewSetClass-based viewsで応答をカスタマイズする2つの方法があります

ソリューション1:カスタムviews.py

class StoryViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.AllowAny,)
    queryset = Story.objects.all()
    serializer_class = StorySerializer

    def retrieve(self, request, *args, **kwargs):
        # ret = super(StoryViewSet, self).retrieve(request)
        return Response({'key': 'single value'})

    def list(self, request, *args, **kwargs):
        # ret = super(StoryViewSet, self).list(request)
        return Response({'key': 'list value'})

ソリューション2:カスタムserializers.py(このソリューションをお勧めします)

class StorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Story
        fields = "__all__"

    def to_representation(self, instance):
        ret = super(StorySerializer, self).to_representation(instance)
        # check the request is list view or detail view
        is_list_view = isinstance(self.instance, list)
        extra_ret = {'key': 'list value'} if is_list_view else {'key': 'single value'}
        ret.update(extra_ret)
        return ret
0
HoangYell