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返回狀態。
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)
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
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)
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路由,有多個註冊多個便可