實例化: v1 = ["view.xxx.path.Role","view.xxx.path.Group",] 可以循環,循環出來的每一個不能實例化 如果把v1循環弄成每一個對象列表,通過rsplit切割,在通過importlib.import_module拿到每一個路徑,在通過getattr把它的類名拿過來,
這個類加括號就是實例化想 for item in v1: m = importlib.import_module('view.xxx.path') cls = getattr(m,'Role') cls() from view.xxx.path import Role,Group v2 = [Group,Role] 這個可以循環每一個實例化 for item in v2: #循環V2的每一個元素加括號,就是實例化 item()
rest_Framework的規范:
按順序:它的method的不同,原來沒有考慮,原來是url區分,現在通過method來區分,method的不同提交方式不同,緊接着一般是面向資源的就是把url變成名詞,接下就是返回值,以前沒有考慮狀態碼,現在有考慮狀態碼。(一般有get,post方法,還有put,delete等方法)
一、Django rest_Framework框架
----為什么用Django rest_Framework框架?
----首先沒有Django rest_Framework框架用django也是可以做出來的,只不過它為我們提供一些API常用的功能,比如:(認證,權限,限流,有了這些我們只需要寫個類已配置,它就能當都市圖用,還能全局配置,如果自己寫還得寫中間件,寫裝飾器來實現,通過Django rest_Framework框架,他已經把規則寫好,只需要寫類,只需實現方法,返回值就可以)實現了一部分功能。
----設計比較好
----單獨視圖+全局配置 =>Dajngo中間件(importlib/反射)=>動態配置課擴展(短信,郵件,微信等提醒)
二、Django rest_Framework原理?
先開始在路由,路由.as_view:
點擊as_view
請求進來,走完以上,才走self.dispatch()
走self.dispatch()流程如下地址:http://www.cnblogs.com/mengqingjian/p/8419563.html
三、版本
a.根據url的不同來來操作,版本控制
先在setting中注冊

from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ #url(r'^admin/', admin.site.urls), url(r'^api/(?P<version>[v1|v2]+)/', include('api.urls')), # url(r'^api/', include('api.urls')), url(r'^backend/', include('backend.urls')), ]

REST_FRAMEWORK = { 'VERSION_PARAM':'version', 'DEFAULT_VERSION':'v1', 'ALLOWED_VERSIONS':['v1','v2'], # 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning" 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning" }

from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.authentication import BasicAuthentication from rest_framework.versioning import QueryParameterVersioning,URLPathVersioning,HostNameVersioning from rest_framework.renderers import BrowsableAPIRenderer,JSONRenderer class UsersView(APIView): # 基於url傳參 # versioning_class = QueryParameterVersioning # 基於URL http://127.0.0.1:8001/api/v2/users/ # versioning_class = URLPathVersioning # 基於子域名 http://v1.luffy.com/users/ # versioning_class = HostNameVersioning def get(self,request,*args,**kwargs): self.dispatch # print(request.version) # QueryParameterVersioning().detemiin_version() # print(request.versioning_scheme) # QueryParameterVersioning() # 當前版本一樣的URL # url = request.versioning_scheme.reverse(viewname='u',request=request) # print(url) # 當前版本不一樣的URL # from django.urls import reverse # url = reverse(viewname='u',kwargs={'version':'v2'}) # print(url) return Response('...')

from django.conf.urls import url,include from . import views urlpatterns = [ url(r'^users/', views.UsersView.as_view(),name='u'), ]
b、
HostName urlpatterns = [ #url(r'^admin/', admin.site.urls), url(r'^api/', include('api.urls')), ] urlpatterns = [ url(r'^users/', views.UsersView.as_view(),name='u'), ] class UsersView(APIView): def get(self,request,*args,**kwargs): self.dispatch print(request.version) # QueryParameterVersioning().detemiin_version() print(request.versioning_scheme) # QueryParameterVersioning() REST_FRAMEWORK = { 'VERSION_PARAM':'version', 'DEFAULT_VERSION':'v1', 'ALLOWED_VERSIONS':['v1','v2'], 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning" } # C:\Windows\System32\drivers\etc # vim /etc/hosts 127.0.0.1 v1.luffy.com 127.0.0.1 v2.luffy.com
四、rest framework解析器
請求的數據進行解析:請求體進行解析。表示服務端可以解析的數據格式的種類。
Content-Type: application/url-encoding..... request.body request.POST Content-Type: application/json..... request.body request.POST 客戶端: Content-Type: application/json '{"name":"alex","age":123}' 服務端接收: 讀取客戶端發送的Content-Type的值 application/json parser_classes = [JSONParser,] media_type_list = ['application/json',] 如果客戶端的Content-Type的值和 application/json 匹配:JSONParser處理數據 如果客戶端的Content-Type的值和 application/x-www-form-urlencoded 匹配:FormParser處理數據 配置: 單視圖: class UsersView(APIView): parser_classes = [JSONParser,] 全局配置: REST_FRAMEWORK = { 'VERSION_PARAM':'version', 'DEFAULT_VERSION':'v1', 'ALLOWED_VERSIONS':['v1','v2'], # 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning" 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning", 'DEFAULT_PARSER_CLASSES':[ 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', ] }

from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ #url(r'^admin/', admin.site.urls), url(r'^api/(?P<version>[v1|v2]+)/', include('api.urls')), # url(r'^api/', include('api.urls')), url(r'^backend/', include('backend.urls')), ]

REST_FRAMEWORK = { 'VERSION_PARAM':'version', 'DEFAULT_VERSION':'v1', 'ALLOWED_VERSIONS':['v1','v2'], # 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning" 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning", 'DEFAULT_PARSER_CLASSES':[ 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', ] }

from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.authentication import BasicAuthentication from rest_framework.versioning import QueryParameterVersioning,URLPathVersioning,HostNameVersioning from rest_framework.renderers import BrowsableAPIRenderer,JSONRenderer from rest_framework.parsers import JSONParser,FormParser from rest_framework.request import Request class UsersView(APIView): def get(self,request,*args,**kwargs): self.dispatch return Response('...') def post(self,request,*args,**kwargs): # # application/json # print(request._request.body) # b"xxxxx" decode() json.loads # print(request._request.POST) # 無 # # # www-form-url-encode # print(request._request.body) # print(request._request.POST) # print(request.data) # print(request.POST) # print(request.FILES) request.data return Response('...')

from django.conf.urls import url,include from . import views urlpatterns = [ url(r'^users/', views.UsersView.as_view(),name='u'), ]
五、 rest framework序列化+Form
序列化:
對象 -> 字符串 序列化
字符串 -> 對象 反序列化
目的:
解決QuerySet序列化問題
序列化:
a、基本操作
class UsersSerializer(serializers.Serializer): name = serializers.CharField() pwd = serializers.CharField() class UsersView(APIView): def get(self,request,*args,**kwargs): self.dispatch # 方式一: # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title") # return Response(user_list) # 方式二之多對象 # user_list = models.UserInfo.objects.all() # ser = UsersSerializer(instance=user_list,many=True) # return Response(ser.data) # 方式二之單對象 user = models.UserInfo.objects.all().first() ser = UsersSerializer(instance=user, many=False) return Response(ser.data)
b、跨表
class UsersSerializer(serializers.Serializer): name = serializers.CharField() pwd = serializers.CharField() group_id = serializers.CharField() xxxx = serializers.CharField(source="group.title") x1 = serializers.CharField(source="group.mu.name") class UsersView(APIView): def get(self,request,*args,**kwargs): self.dispatch # 方式一: # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title") # return Response(user_list) # 方式二之多對象 user_list = models.UserInfo.objects.all() ser = UsersSerializer(instance=user_list,many=True) return Response(ser.data)
c、復雜序列化
解決方案一: class MyCharField(serializers.CharField): def to_representation(self, value): data_list = [] for row in value: data_list.append(row.name) return data_list class UsersSerializer(serializers.Serializer): name = serializers.CharField() # obj.name pwd = serializers.CharField() # obj.pwd group_id = serializers.CharField() # obj.group_id xxxx = serializers.CharField(source="group.title") # obj.group.title x1 = serializers.CharField(source="group.mu.name") # obj.mu.name # x2 = serializers.CharField(source="roles.all") # obj.mu.name x2 = MyCharField(source="roles.all") # obj.mu.name 解決方案二: class MyCharField(serializers.CharField): def to_representation(self, value): return {'id':value.pk, 'name':value.name} class UsersSerializer(serializers.Serializer): name = serializers.CharField() # obj.name pwd = serializers.CharField() # obj.pwd group_id = serializers.CharField() # obj.group_id xxxx = serializers.CharField(source="group.title") # obj.group.title x1 = serializers.CharField(source="group.mu.name") # obj.mu.name # x2 = serializers.CharField(source="roles.all") # obj.mu.name x2 = serializers.ListField(child=MyCharField(),source="roles.all") # obj.mu.name 解決方案三(*): class UsersSerializer(serializers.Serializer): name = serializers.CharField() # obj.name pwd = serializers.CharField() # obj.pwd group_id = serializers.CharField() # obj.group_id xxxx = serializers.CharField(source="group.title") # obj.group.title x1 = serializers.CharField(source="group.mu.name") # obj.mu.name # x2 = serializers.CharField(source="roles.all") # obj.mu.name # x2 = serializers.ListField(child=MyCharField(),source="roles.all") # obj.mu.name x2 = serializers.SerializerMethodField() def get_x2(self,obj): obj.roles.all() role_list = obj.roles.filter(id__gt=1) data_list = [] for row in role_list: data_list.append({'pk':row.pk,'name':row.name}) return data_list
以上三種都是使用相同的視圖:
class UsersView(APIView): def get(self,request,*args,**kwargs): self.dispatch # 方式一: # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title") # return Response(user_list) # 方式二之多對象 user_list = models.UserInfo.objects.all() # [obj1,obj2,obj3] ser = UsersSerializer(instance=user_list,many=True) return Response(ser.data)
d. 基於Model
class UsersSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" # fields = ['name', 'pwd','group'] depth = 1 class UsersView(APIView): def get(self,request,*args,**kwargs): self.dispatch # 方式一: # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title") # return Response(user_list) # 方式二之多對象 user_list = models.UserInfo.objects.all() # [obj1,obj2,obj3] ser = UsersSerializer(instance=user_list,many=True) return Response(ser.data)
e. 生成URL
class UsersSerializer(serializers.ModelSerializer): group = serializers.HyperlinkedIdentityField(view_name='detail') class Meta: model = models.UserInfo fields = "__all__" fields = ['name', 'pwd','group'] depth = 1 class UsersView(APIView): def get(self,request,*args,**kwargs): self.dispatch # 方式一: # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title") # return Response(user_list) # 方式二之多對象 user_list = models.UserInfo.objects.all() # [obj1,obj2,obj3] ser = UsersSerializer(instance=user_list,many=True,context={'request':request}) return Response(ser.data)
f. 全局生成URL
class UsersSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = models.UserInfo fields = "__all__" # fields = ['id','name','pwd'] class UsersView(APIView): def get(self,request,*args,**kwargs): self.dispatch # 方式一: # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title") # return Response(user_list) # 方式二之多對象 user_list = models.UserInfo.objects.all() # [obj1,obj2,obj3] ser = UsersSerializer(instance=user_list,many=True,context={'request':request}) return Response(ser.data)
請求數據驗證:
a、
class PasswordValidator(object): def __init__(self, base): self.base = base def __call__(self, value): if value != self.base: message = '用戶輸入的值必須是 %s.' % self.base raise serializers.ValidationError(message) def set_context(self, serializer_field): """ This hook is called by the serializer instance, prior to the validation call being made. """ # 執行驗證之前調用,serializer_fields是當前字段對象 pass class UsersSerializer(serializers.Serializer): name = serializers.CharField(min_length=6) pwd = serializers.CharField(error_messages={'required': '密碼不能為空'}, validators=[PasswordValidator('666')])
b、
class PasswordValidator(object): def __init__(self, base): self.base = base def __call__(self, value): if value != self.base: message = '用戶輸入的值必須是 %s.' % self.base raise serializers.ValidationError(message) def set_context(self, serializer_field): """ This hook is called by the serializer instance, prior to the validation call being made. """ # 執行驗證之前調用,serializer_fields是當前字段對象 pass class UsersSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" extra_kwargs = { 'name': {'min_length': 6}, 'pwd': {'validators': [PasswordValidator(666), ]} }
使用:
class UsersView(APIView): def get(self,request,*args,**kwargs): self.dispatch # 方式一: # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title") # return Response(user_list) # 方式二之多對象 user_list = models.UserInfo.objects.all() # [obj1,obj2,obj3] ser = UsersSerializer(instance=user_list,many=True,context={'request':request}) return Response(ser.data) def post(self,request,*args,**kwargs): ser = UsersSerializer(data=request.data) if ser.is_valid(): print(ser.validated_data) else: print(ser.errors) return Response('...')