zoukankan      html  css  js  c++  java
  • Python之Django rest_Framework(2)

    实例化:
    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')),
    ]
    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 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('...')
    views.py
    from django.conf.urls import url,include
    from . import views
    urlpatterns = [
        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: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')),
    ]
    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 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('...')
    views.py
    from django.conf.urls import url,include
    from . import views
    urlpatterns = [
        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('...')

      

  • 相关阅读:
    UVa
    UVa
    USACO
    USACO
    USACO
    Floyed算法学习
    POJ
    POJ
    codeforces 796C Bank Hacking
    codeforces 796B Find The Bone
  • 原文地址:https://www.cnblogs.com/mengqingjian/p/8428053.html
Copyright © 2011-2022 走看看