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:\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‘)),
]

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

时间: 2024-07-31 02:04:45

Python之Django rest_Framework(2)的相关文章

python之Django rest_framework总结

一.rest api    a.api就是接口         如: - http://www.oldboyedu.com/get_user/                - http://www.oldboyedu.com/get_users/    b.api的两个用途         1.为别人提供服务         2.前后端分离 二.restful     a.--字面意思:表征状态转移     b.面向资源编程,对互联网上的任意东西都视为资源          如:- http:

Python之Django rest_Framework(3)

补充:  为什么要前后端分离:       a.因为前端它有自己框架,这样它的效率就非常高       b.不做前后端分离,公司如果既有客户端,又有app这种情况下你就的写两遍 django restful框架好处:       帮助我们写了好多组件比如:       a.认证:有类,类中的方法authenticate/authenticate_header,它的返回值有None,元组,异常.如果返回值为None那就不管,它是匿名用户.       b.权限:有类,类中的方法:has_permi

Django rest_framework实现增删改查接口

目录 Django rest_framework实现增删改查接口 写接口前的知识准备 __all__的使用方法 序列化类配置 Response二次封装 连表深度查询 单查群查接口 单删群删接口 单增,群增接口 整体单改群改接口 局部修改数据 视图给序列化传参 Django rest_framework实现增删改查接口 本文使用Django的rest_framework框架的ModelSerializer模块和ListSerializer模块实现单查群查.单删群删.单增群增.单改群改接口. 写接口

Python和Django的Third Libraby分类汇总

这些第三方包与Python和Django一起构成了强大的生态系统,自己在开发时大大减小工作难度和工作量, 这些包基本上能满足我们的大部分需求.人与人的差距,其中一点是你知道的比他多,这样你就能大大提高 开发效率.Awesome-Python受Awesom-PHP的启发,而Awesome-Django又受Awesome-Python的启 发. https://github.com/vinta/awesome-python https://github.com/rosarior/awesome-dj

Django rest_framework 实用技巧

前言: 最近工作中需要用到Django rest_framework框架做API, 边学边写,记录了一些实际工作中需要用到的功能,不是很全也不系统,以后需要什么功能可以在这查询. 后续还会更新其它的用法 1 #################################################################### 2 ########安装和简单使用 3 ###### 准备工作 4 pip install rest_framework # 安装 5 6 INSTALL

Python、Django和Mysql安装步骤

很多初学者都问Python和Django怎么安装,这里我们就简单地介绍一下这两个软件在Windows 2003下的安装步骤. 一.下载并安装Python Python 官方下载地址:http://www.python.org/ftp/python/ 我们这里选择的是 Python 2.7.2 .虽然目前最新版是Python 3.2.2, 但是Django目前还不支持 Python 3.2.2. 安装步骤很简单,双击安装包开始安装,这里我们安装到 D:\Python,如图1, 图1 单击“Next

[Python] 利用Django进行Web开发

第一步:下载并安装django 首先,在Django官网上下载适合自己Python的Django版本,在安装Django前首先确定你已成功安装了python.         Windows系统下安装Django: 解压缩下载的Django压缩包,找到里面的setup.py文件,然后打开cmd命令窗口,在其对应的路径下执行如下命令: python setup.py install Linux系统下安装Django: 以此在shell中输入如下命令: $ tar xzvf Django-*.tar

python web——Django架构

环境:windows/linux/OS 需要的软件:Firefox 浏览器(别的也可以 不过firfox和python的webdriver兼容性好) git版本控制系统(使用前要配置 用户 编辑器可以用系统的 notepad) python包管理工具pip(3.4以及之后的版本在python中集成了 3.4以前的需要安装 命令行中执行which pip3 返回路径即表示安装完成) python(在安装时选择把 python.exe加入系统路径中) Django 1.11 (命令行pip3 ins

django rest_framework中将json输出字符强制为utf-8编码

最近在和日本外包合作开发JIRA对接发布系统的版本单时, 遇到这个问题. 就是我们这边的输出浏览器显示为中文,而到了JIRA端就出现乱码. 查了文档,原来django rest_framework的默认json是没指定编码的, 需要随接收方的环境编码来显示. 于是,因为项目进度,我们对了强制编码操作. 查看rest framework的源代码: class JSONRenderer(BaseRenderer): """ Renderer which serializes to