Django REST框架APIView与Viewset

时间:2020-09-30 15:24:56

标签: django-rest-framework

我当前正在使用APIView作为url('/api/events/<int:pk>'),但是我不能将同一APIView用于list视图,因为之间没有区别列表(获取全部)和详细信息(获取1)。该视图与模型无关,因为我正在调用外部API。

ViewSet确实在列表和检索之间有区别,但是如果我使用它,则必须使用serializer_classes。但是,我在此视图上没有序列化器。

我知道我可以创建第二个APIView,因此我在细节和列表视图上都有1个,但是我发现这有点麻烦。一班上课比较干净。

什么是最好的?

示例:”

class TestView(APIView):
    """
    Test123123o8
    """
    serializer_class = Test1Serializer

    #this methods acts on the /test GET route
    def get(self, request):
        return Response(Test.objects.all())

    # route that acts on the DETAIL route (for example '/api/test/1'). 
    # How to implement this in the URL?
    def get_detail(self, request, pk):
        return Response(test.objects.get(pk=pk))
    
    def post(self, request, format=None):
        serializer = Test1Serializer(data=request.data)
        if serializer.is_valid():
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

1 个答案:

答案 0 :(得分:1)

使用APIView

出于演示目的,我仍然在retrieve/list方法内使用queryset,但这不是强制性的,您应该在其中放置自己的逻辑。

class TestAPIView(views.APIView):

    def get(self, request, *args, **kwargs):
        if 'pk' in kwargs:
            return self.retrieve(request, *args, **kwargs)
        else:
            return self.list(request, *args, **kwargs)

    def retrieve(self, request, *args, **kwargs):
        instance = Test.objects.get(pk=kwargs['pk'])
        serializer = TestSerializer(instance=instance)
        return Response(serializer.data)

    def list(self, request, *args, **kwargs):
        queryset = Test.objects.all()
        serializer = TestSerializer(queryset, many=True)
        return Response(serializer.data)

然后在urls.py中添加以下行:

url(r'^test/$', TestAPIView.as_view(), name='test-list'),
url(r'^test/(?P<pk>[0-9]+)/$', TestAPIView.as_view(), name='test-detail'),

,或者在更新的Django版本中,您可以使用path

path('test/', TestAPIView.as_view(), name='test-list'),
path('test/<int:pk>/', TestAPIView.as_view(), name='test-detail),

使用ViewSet

您需要在URL定义中将request方法的映射添加到函数中。

from rest_framework import viewsets

class TestViewSet(viewsets.ViewSet):

    def retrieve(self, request, *args, **kwargs):
        instance = Test.objects.get(pk=kwargs['pk'])
        serializer = TestSerializer(instance=instance)
        return Response(serializer.data)

    def list(self, request, *args, **kwargs):
        queryset = Test.objects.all()
        serializer = TestSerializer(queryset, many=True)
        return Response(serializer.data)

然后在urls.py中添加以下行:

url(r'^test/$', TestViewSet.as_view({'get': 'list'}), name='test-list'),
url(r'^test/(?P<pk>[0-9]+)/$', TestViewSet.as_view({'get': 'retrieve'}), name='test-detail'),

,或者在较新的Django版本中,您可以使用path

path('test/', TestViewSet.as_view({'get': 'list'}), name='test-list'),
path('test/<int:pk>/', TestViewSet.as_view({'get': 'retrieve'}), name='test-detail),