Django-DRF-視圖的演變

 

 

版本一(基於類視圖APIView類)

views.py:前端

APIView是繼承的Django View視圖的。python

 1 from .serializers import UserSerializers    #導入當前目錄配置好的序列化器 
 2 from .models import User                    #導入數據庫
 3 from rest_framework.views import APIView    #導入APIView 
 4 from rest_framework.response import Response  #該模塊返回json數據
 5 from rest_framework import status           #內置狀態碼模塊
 6 
 7 class UserAPIView(APIView):          #查看全部及添加數據視圖
 8     def get(self,request):  9         users = User.objects.all()          #獲取數據庫裏全部數據
10         ser = UserSerializers(instance=users,many=True) #進行序列化操做,指定更多集合對象
11         return Response(ser.data,status=200)#返回成功數據
12 
13     def post(self,request):          #添加數據
14         ser = UserSerializers(data=request.data)#接收前臺傳輸數據
15         if ser.is_valid():                  #判斷書否合法raise_exception=True加次參數表示不合法拋出異常,默認false
16             ser.save()                      #保存
17             return Response(ser.data,status=200) 18         return Response(ser.errors)         #返回錯誤信息
19 
20 class UserSingleView(APIView):       #單條查詢,改,刪除視圖
21     def get(self,request,pk): 22         user = User.objects.get(id=pk)      #查詢單條集合對象
23         ser = UserSerializers(instance=user)#序列化數據
24         return Response(ser.data) 25 
26     def put(self,request,pk):        #修改
27         user = User.objects.get(pk=pk) 28         ser = UserSerializers(instance=user,data=request.data)  #注意指定參數
29         if ser.is_valid(): 30  ser.save() 31             return Response(ser.data,status=200) 32         return Response(ser.errors) 33 
34     def delete(self,request,pk):     #刪除操做
35         User.objects.get(pk=pk).delete() 36         return Response(status=status.HTTP_200_OK)
代碼說明: 1. 使用類視圖,定義兩個類並繼承APIView類視圖; 2. 在類視圖裏編寫:增刪改查方法,經過HttpResponse返回狀態。

serializers.py

 
 

from rest_framework import serializers #導入序列

from .models import User #導入表

class UserSerializers(serializers.Serializer):#注意繼承的類
    nick_name = serializers.CharField(max_length=20,required=True)    #required=True設置必須驗證
    gender = serializers.BooleanField(default=0,required=False)
   def create(self, validated_data):         #建立數據的操做
        return User.objects.create(**validated_data)

   def update(self, instance, validated_data):#修改數據的操做
    
instance接收的是數據庫查詢的單個對象,validated_data爲前端傳輸的數據
instance.nick_name
= validated_data.get('nick_name',instance.nick_name) instance.gender = validated_data.get('gender',instance.gender) instance.save()          #取出值每一個字段進行保存 return instance

版本二(使用混合 mixins)數據庫

繼承generics和mixins裏的方法,稱之爲「混合」django

views.py:json

 

 1 from rest_framework import mixins, generics  # 導入相應模塊
 2 # mixins就是一個類,只不過這個類裏定義了不少操做數據的方法
 3 from .serializers import UserModelSerializer
 4 class UserGenericAPIview(generics.GenericAPIView,mixins.ListModelMixin,mixins.CreateModelMixin):
 5     queryset = UserInfo.objects.all()      # queryset指定集合數據是從哪一個數據庫來
 6     serializer_class =UserModelSerializer  # serializer_class配置序列化器類UserModelSerializer
 7 
 8     # 調用mixins.ListModelMixin類的list()方法
 9     def get(self,request):
10         return self.list(request)
11 
12     # 調用mixins.CreateModelMixin類的create()方法 
13     def post(self,request):
14         return self.create(request)
15 
16 class UserGenericSingleView(generics.GenericAPIView,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin):
17     queryset = UserInfo.objects.all()
18     serializer_class = UserModelSerializer
19 
20     # 調用mixins.RetrieveModelMixin類的retrieve()方法
21     def get(self,request,pk):  #檢索
22         return self.retrieve(request)
23 
24     # 調用mixins.UpdateModelMixin類的update()方法
25     def put(self,request,pk):  #修改
26         return self.update(request)
27 
28     # 調用mixins.DestroyModelMixin類的destroy()方法
29     def delete(self,request,pk):  #破壞
30         return self.destroy(request)
代碼說明:
1. 爲何要繼承mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin等這一堆方法呢?
答:好比咱們自定義寫了delete方法,而這個方法會自動、只能的去調用mixins.DestroyModelMixin這個類裏面的動做。

 

serializers,pyapp

1 from rest_framework import serializers
2 from .models import UserInfo
3 
4 class UserModelSerializer(serializers.ModelSerializer):
5     class Meta:
6         #配置model爲UserInfo
7         model = UserInfo  
8         fields = "__all__"   #fields配置要序列化的字段,"__all__"表示全部的字段都序列化

在上個版本中,queryset和serializer屬性都是經過本身聲明去使用的;ide

這個版本繼承使用混合繼承了generics,經過查看generics源碼發現以下:函數

class GenericAPIView(views.APIView):
···
    queryset = None
    serializer_class = None
···

版本三(使用混合高級版)

views.py:post

1 from rest_framework import generics
2 
3 class UserListAPIView(generics.ListCreateAPIView):
4     queryset = UserInfo.objects.all()
5     serializer_class = UserModelSerializer
6 
7 class UserSingleView(generics.RetrieveUpdateDestroyAPIView):
8     queryset = UserInfo.objects.all()
9     serializer_class = UserModelSerializer

這幾行代碼搞定上面全部功能,只須要傳入queryset和serializer便可,這什麼原理呢?ui

一、第二版本中,咱們繼承了generics.GenericAPIView類視圖,本身寫了兩個get和post方法對吧,那generics的另外一個方法把這兩個事情也幹了,咱們只須要繼承便可。
二、對的,這個方法就是generics.ListCreateAPIView,咱們且看看它的源碼,你就明白了
class ListCreateAPIView(mixins.ListModelMixin,
                        mixins.CreateModelMixin,
                        GenericAPIView):       
    """
    Concrete view for listing a queryset or creating a model instance.
    """
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

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

版本四(視圖集 ViewSet

views.py:

 1 from rest_framework import viewsets,mixins
 2 class GennericViewsSet(viewsets.GenericViewSet,
 3                        mixins.CreateModelMixin,
 4                        mixins.ListModelMixin,
 5                        mixins.RetrieveModelMixin,
 6                        mixins.UpdateModelMixin,
 7                        mixins.DestroyModelMixin
 8                        ):
 9     queryset = UserInfo.objects.all()
10     serializer_class = Userserializer

這個版本views裏就寫了一個類視圖,以前的全部版本都是寫一個List和一個Detail視圖的,

這個類 繼承了viewsets.GenericViewSet,其餘的方法都是mixins的viewsets

GenericViewSet繼承了ViewSetMixin方法,從ViewSetMixin的源碼裏能看到能夠改寫as_view的信息,來達到定製路由的效果

class ViewSetMixin(object):
    @classonlymethod
    def as_view(cls, actions=None, **initkwargs):
      ······
        if not actions:
            raise TypeError("The `actions` argument must be provided when "
                            "calling `.as_view()` on a ViewSet. For example "
                            "`.as_view({'get': 'list'})`")

urls.py:

1 from django.conf.urls import url
2 from . import views
3 
4 urlpatterns = [
5     url(r'^$',views.GennericViewsSet.as_view({'get':'list',"post": "create"})),   #注意這裏的寫法
6     url(r'^users/(?P<pk>\d+)/$',views.GennericViewsSet.as_view({'get':'retrieve','put':'update','delete':'destroy'}))
7 ]

版本五 (終極大法:寫項目選用此法)

views.py:

1 from rest_framework.viewsets import ModelViewSet
2 class ZhongJiBanView(ModelViewSet):
3     queryset = UserInfo.objects.all()
4     serializer_class = UserModelSerializer

直接繼承了一個巨無霸(ModelViewSet),這個巨無霸將全部的功能都封裝到一塊。至關於把咱們從初版到第三版寫的全部事情都幹了,

按照老規矩,咱們來看看它的源碼:

class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):
    """
    A viewset that provides default `create()`, `retrieve()`, `update()`,
    `partial_update()`, `destroy()` and `list()` actions.
    """
    pass

從源碼中能看出,ModelViewSet所繼承的視圖類

urls.py

 

1 from . import views
2 from rest_framework.routers import DefaultRouter
3 rount = DefaultRouter()
4 rount.register('user',views.ZhongjiBanView)
5 urlpatterns = []
6 urlpatterns += rount.urls

最終版的規則使用了drf的DefaultRouter函數,經過實例化DefaultRouter獲得route對象,使用route.register()你的app路由,有多個註冊多個便可

相關文章
相關標籤/搜索