实例化:
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:WindowsSystem32driversetc
# 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('...')