Python之Django rest_Framework(2)

2018-02-08 07:53:59来源:cnblogs.com作者:孟庆健人点击

分享
实例化: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,includefrom django.contrib import adminurlpatterns = [    #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')),]
url
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"}
settings.py配置
from django.shortcuts import renderfrom rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.authentication import BasicAuthenticationfrom rest_framework.versioning import QueryParameterVersioning,URLPathVersioning,HostNameVersioningfrom rest_framework.renderers import BrowsableAPIRenderer,JSONRendererclass 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('...')
views.py
from django.conf.urls import url,includefrom . import viewsurlpatterns = [    url(r'^users/', views.UsersView.as_view(),name='u'),]
url.py -----和view在一个APP中的路由

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,includefrom django.contrib import adminurlpatterns = [    #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')),]
url.py
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',    ]}
setting.py
from django.shortcuts import renderfrom rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.authentication import BasicAuthenticationfrom rest_framework.versioning import QueryParameterVersioning,URLPathVersioning,HostNameVersioningfrom rest_framework.renderers import BrowsableAPIRenderer,JSONRendererfrom rest_framework.parsers import JSONParser,FormParserfrom rest_framework.request import Requestclass 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('...')
views.py
from django.conf.urls import url,includefrom . import viewsurlpatterns = [    url(r'^users/', views.UsersView.as_view(),name='u'),]
url.py 和view一个APP下的文件

五、 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('...')

  

微信扫一扫

第七城市微信公众平台