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

  

原文地址:https://www.cnblogs.com/mengqingjian/p/8428053.html