[django-rest-framework]02.Class-based Views,基於類的視圖!

本人普通一本,正值大三,爲了能有好的就業,痛定思痛戒掉遊戲!鞭策自己至少一週一篇博客

  • 學習目標:學校課內基礎打紮實,課外學會語言框架,同時提升英語閱讀水平
  • 學習路線(自擬):vue -> djangorestframework -> goland
  • 畢業前想:用前後端分離建成自己的小站,做一款網絡遊戲(愛好而已)

關於本篇djangorestframwork

內容皆會上傳到我的github上:https://github.com/BadbadLoli/django-rest-framework-study

本篇參照官網教程:https://www.django-rest-framework.org/tutorial/3-class-based-views/

學習爲主,如有紕漏請大神指正


我們可以使用類視圖而不是函數視圖,這是一個強大的模式,它允許我們重用公共的功能,並幫助我們簡化代碼

用類視圖重寫我們的視圖函數

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status


class SnippetList(APIView):
    # 展示所有/創造一條snippet
    def get(self, request, format=None):
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = SnippetSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class SnippetDetail(APIView):
    # 檢索,更新或刪除一條snippet實例
    def get_object(self, pk):
        try:
            return Snippet.objects.get(pk=pk)
        except Snippet.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        snippet = self.get_object(pk)
        serializer = SnippetSerializer(snippet)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        snippet = self.get_object(pk)
        serializer = SnippetSerializer(snippet, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        snippet = self.get_object(pk)
        snippet.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

既然是基於類的視圖,urls.py也要進行適當的改變

from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views

urlpatterns = [
    path('snippets/', views.SnippetList.as_view()),
    path('snippets/<int:pk>/', views.SnippetDetail.as_view()),
]

urlpatterns = format_suffix_patterns(urlpatterns)

使用mixins

使用類視圖的一大好處是,它可以允許我們輕鬆的組合各種可重用的行爲

我們使用的create/retrieve/update/delete這些通用操作,在drf裏都有對應的mixin類實現

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework import mixins
from rest_framework import generics

class SnippetList(mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  generics.GenericAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)
        

class SnippetDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

我們使用基類GenericAPIView構建視圖,並添加了ListModelMixinCreateModelMixinGenericAPIView提供核心功能,而mixin類提供.list().create().retrieve().update().destroy()操作,然後將其綁定到getpost請求上

使用通用的類視圖

通過使用mixin類,我們重寫了視圖,並比之前使用了更少的代碼,但是代碼可以更加簡潔,drf給我們提供了一組已經混合了多種mixin類的通用視圖,用來進一步簡化view.py

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework import generics


class SnippetList(generics.ListCreateAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer


class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer

哇,真簡潔。我們已經獲得了大量的資源,我們的代碼看起來很好,乾淨,符合Django的習慣。接下來,我們將進入本教程的第4部分,在這裏我們將瞭解如何處理API的身份驗證和權限。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章