Django中rest framework框架的十大组件流程及源码概述

开发模式

普通的开发方式(前后端放在一起写)
前后端分离(Ajax)

后端开发

后端为前端提供URL(API/接口的开发)
注: 返回HttpResponse(render和redirect就用不上)
举例:第一个简单的接口(不依赖任何工具)

反射:

什么是反射:

通过字符串映射object对象的方法或者属性

反射的实际应用场景:

在我们做接口自动化的时候,需要通过不同的请求方式,调用不同的函数

常用四大请求:

get post put delete
Django中rest framework框架的十大组件流程及源码概述_第1张图片

rest framework的第一组件

认证:

首先

导入rest_framework.views中的 APIView方法
from rest_framework.views import APIView  

我们来看一段伪代码,MyClassView继承了APIView就有了APIView的功能

class APIView(View):
	pass

class MyClassView(APIView):
	pass
在class类里面的(APIView)在pycharm按住ctrl点击APIView,就会跳到这个方法里面 "例如最后面的大写字母,“DEFAULT_AUTHENTICATION_CLASSES"就是各个组件的配置名”

Django中rest framework框架的十大组件流程及源码概述_第2张图片

我们开始进入认证的操作流程:

首先在model中创建两个模型

Django中rest framework框架的十大组件流程及源码概述_第3张图片

from django.db import models


# Create your models here.
class UserInfo(models.Model):
    """用户表"""
    user_type_choices = (
        (1, "普通用户"),
        (2, "VIP"),
        (3, "SVIP")
    )
    user_type = models.IntegerField(choices=user_type_choices)
    username = models.CharField(max_length=32, unique=True)
    password = models.CharField(max_length=64)


class UserToken(models.Model):
    """token表"""
    user = models.OneToOneField(to="UserInfo")
    token = models.CharField(max_length=64)

一个是用户表 一个是token表 用户表中加入了用户类型 token表关联用户表 成一对一的类型 所以一个用户只能有一个token

然后我们开始写view视图 首先我们要创建token生成加密字符

#创建md5函数 继承token模型的user对象
def md5(user):
	#导入哈希加密
	import hashlib
	#导入时间
	import time
	#变量名ctime 接收现在的时间转为字符str类型
	ctime = str(time.time())
	#将user对象转为字节并用哈希md5加密 变为16进制字符
	m = hashlib.md5(bytes(user, encoding="utf-8"))
	#修改并加入时间戳
    m.update(bytes(ctime, encoding="utf-8"))
    #并返回
    return m.hexdigest()
	

另一种写法

import hashlib
import time
#创建token
def createToken(user):

    md5 = hashlib.md5()
    #修改账户名字节并加入时间戳 和utf-8(时间戳)
    md5.update(bytes(user + str(time.time()), encoding='utf-8'))
    #返回摘要,作为十六进制数据字符串值
    token = md5.hexdigest()
    #返回给token
    return token

然后设置登录功能:

#设置登录类
class AuthView(APIView):
	# 提交我们用 内置源码的post请求
	def post(self,request,*args,**kwargs):
		# 设置状态码
		ret = {"state_code": 1000, "msg": None}
		#判断异常
		try:
			#原生_request改写request方法 获取前端表单里面的用户名
			username = request._request.POST.get("username")
			#获取前端表单里面的密码
			password = request._request.POST.get("password")
			# 用变量名obj 接收数据库里的信息并进行 前端表单与数据库的匹配
			obj = models.UserInfo.object.filter(username=username,password=password).first()
			#然后进行判断 如果匹配的内容不对 
	        if not obj:
	        	# 就发送状态码 1001
               ret["state_code"] = 1001
               # 用户名或者 密码错误
               ret["msg"] = "用户名或者密码错误"
            # 否则为登陆用户创建一个token
            token = md5(username)
            # 存到数据库 存在就更新,不存在就创建
            models.UserToken.objects.update_or_create(user=obj, defaults={"token": token})
            # 发送状态码 
            ret["token"] = token
            #告知请求成功
            ret["msg"] = "请求成功"
        #判断异常
        except Exception as e:
        	# 发送状态码
            ret["state_code"] = 1002
            # 请求异常
            ret["msg"] = "请求异常"
        #返回JsonResponse
        return JsonResponse(ret)
			
		

这时我们在 Django项目 我的应用中myapp就是我的应用里面创建 我的工具包 myutils 里面去创建各种组件的方法 这样看着明显而且 省地方! 随后我们创建auth.py来写我们的 认证组件方法:

Django中rest framework框架的十大组件流程及源码概述_第4张图片

然后进入 auth.py 导入rest_framework.authentication里面的BaseAuthentication方法,导入应用中的模型类,导入判断不包括在内的方法

from rest_framework.authentication import BaseAuthentication

from myapp import models

from rest_framework import exceptions


#创建一个我的认证类 继承BaseAuthentication方法
class MyAuthtication(BaseAuthentication):
	# 设置内置authenticate重写authenticate这个方法
    def authenticate(self, request):
    	# 将用户输入的token用变量接收
        token = request._request.GET.get("token")
        # 然后在数据库进行匹配
        token_obj = models.UserToken.objects.filter(token=token).first()
        # 如果认证失败
        if not token_obj:
        	#就返回失败
            raise exceptions.AuthenticationFailed("用户认证失败")
        # 在 rest framework内部 会将这两个字段赋值给request,以供后续操作使用
        #正确就返回用户和token
        return (token_obj.user, token)
        



# 如果pass 就调用原有的方法
class MyAuthtication_None(BaseAuthentication):
    def authenticate(self, request):
        pass

另一种方法

#创建 我的Authtication
class MyAuthtication(BaseAuthentication):
    #使用authenticate方法
    def authenticate(self, request):
        #获取token
        token = request._request.GET.get('token')
        #进行判断 如果不是token
        if not token:
            #返回元组验证失败
            raise AuthenticationFailed('未登录')
        #否则
        else:
            #在数据库UserToken表中进行比对 从第一个开始
            usertoken = UserToken.objects.filter(token=token).first()
            #如果是usertoken
            if usertoken:
                #就返回用户的token
                return (usertoken.user, token)
            #否则验证失败
            else:
                raise AuthenticationFailed('验证失败')

然后我们在settings设置全局配置

在class类里面的(APIView)在pycharm按住ctrl点击APIView,就会跳到这个方法里面 "例如最后面的大写字母,“DEFAULT_AUTHENTICATION_CLASSES"就是各个组件的配置名”

Django中rest framework框架的十大组件流程及源码概述_第5张图片

将"DEFAULT_AUTHENTICATION_CLASSES":[设置类的路径]

Django中rest framework框架的十大组件流程及源码概述_第6张图片
然后就可以在view视图中加入

 	authentication_classes = []

如果不在settings配置全局设置 就要单独写这个进行验证 所以 我们要先在view中导入

from myapp.myutils.throttle import MyAuthtication

#将登录类里写入 进行认证
authentication_classes = [MyAuthtication]

就像这样

Django中rest framework框架的十大组件流程及源码概述_第7张图片

然后我们试着 在postman 软件中 输入用户名及密码 申请登录尝试我们的代码使用是否正确

输入我们在urls.py中设置的接口 也就是路由

from django.conf.urls import url
from django.contrib import admin
from myapp import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/v1/auth/$', views.AuthView.as_view()),
    ]

然后输入到postman 中 点击body 中的 X-www-form-urlencoded 输入 用户名 密码进行 登录匹配

登录成功

Django中rest framework框架的十大组件流程及源码概述_第8张图片

登录失败

Django中rest framework框架的十大组件流程及源码概述_第9张图片

然后我们去看authenticate这个的源码

    def authenticate(self, request):
        token = request._request.GET.get("token")

首先点击

在class类里面的(APIView)在pycharm按住ctrl点击APIView,然后向下翻找到Django中rest framework框架的十大组件流程及源码概述_第10张图片

     def dispatch(self, request, *args, **kwargs):
        """
        `.dispatch()` is pretty much the same as Django's regular dispatch,
        but with extra hooks for startup, finalize, and exception handling.
        """
        self.args = args
        self.kwargs = kwargs
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request
        self.headers = self.default_response_headers  # deprecate?


        try:
            #进这里 #点击这个
            self.initial(request, *args, **kwargs)

            # Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed

            response = handler(request, *args, **kwargs)

        except Exception as exc:
            response = self.handle_exception(exc)

        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response

找到def dispatch(self, request, *args, **kwargs):中的 self.initial并点击

        try:
           #进这里 #点击这个
           self.initial(request, *args, **kwargs)

然后将会看到:

Django中rest framework框架的十大组件流程及源码概述_第11张图片

		# 代表 认证组件
		self.perform_authentication(request)
		# 代表 权限组件
        self.check_permissions(request)
        # 代表 限流组件
        self.check_throttles(request)

然后 点击self.perform_authentication(request)这个方法

Django中rest framework框架的十大组件流程及源码概述_第12张图片

在这里它封装了 request.user方法 点击request.user然后选择第三个

Django中rest framework框架的十大组件流程及源码概述_第13张图片

在这里封装了self._authenticate() 点击self._authenticate()

Django中rest framework框架的十大组件流程及源码概述_第14张图片
Django中rest framework框架的十大组件流程及源码概述_第15张图片

------------------------------------------------------------------------------------

rest framework的第二组件

权限:

首先 观察我们之前创建的 用户表 用户分为三种类型 三种类型 就代表在登录 验证 或者订单中来实现 这三种权限显示的内容

Django中rest framework框架的十大组件流程及源码概述_第16张图片

我们先在view.py视图中 写好一个订单表 方便在写权限代码时 用权限功能 来使用 订单表 如何用权限显示订单内容

# 创建一个ORDER_DICT字典 输入一些信息
ORDER_DICT = {
    1: {
        "name": "张三",
        "age": 18,
        "gender": "男",
        "orders": [{
            "name": "娃娃",
            "price": 1000
        }]
    },
    2: {
        "name": "李四",
        "age": 20,
        "gender": "女",
        "orders": [{
            "name": "你猜",
            "price": 1200
        }]
    },

}

# 创建OrderView类 继承APIView
class OrderView(APIView):
    """
    订单相关业务
    """
    # 设置get请求
    def get(self, request, *args, **kwargs):
		# 状态码
        ret = {"state_code": 1000, "msg": None, "data": None}
		# 判断异常
        try:
        	# 如果正确 就返回字典的数据
            ret['data'] = ORDER_DICT
        # 错误就返回状态码
        except Exception as e:
            pass
        return JsonResponse(ret)

然后配置路由urls.py进行配置

from django.conf.urls import url
from django.contrib import admin
from myapp import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # 认证接口
    url(r'^api/v1/auth/$', views.AuthView.as_view()),
    # 订单接口
    url(r'^api/v1/order/$', views.OrderView.as_view()),
    ]

在myapp应用中的工具包myutlis中创建permission.py代表权限组件的配置

# 在rest_framework.permissions 导入BasePermission方法
from rest_framework.permissions import BasePermission

# 创建SVIPPermission类 继承BasePermission方法
class SVIPPermission(BasePermission):
	# 状态码
    message = "无权访问"
	# 重写 has_permission方法
    def has_permission(self, request, view):
    	# 如果 用户 user_type 类型 不等于3
        if request.user.user_type != 3:
        	# 就无法访问
            return False
         # 否则可以访问
        return True

这个 def has_permission(self, request, view):方法从哪来? 我们要看里面的源码:

首先点击 self.dispatch() 找到 self.initial(request,*args,**kwargs)点击 进入

Django中rest framework框架的十大组件流程及源码概述_第17张图片

然后点击 代表权限的组件方法Django中rest framework框架的十大组件流程及源码概述_第18张图片

这里会出现 点击这个选择第三个 会出现我们冲的的方法

Django中rest framework框架的十大组件流程及源码概述_第19张图片

随后滚动鼠标 会出现这个方法

Django中rest framework框架的十大组件流程及源码概述_第20张图片

百度翻译一下

“”"
Allows access only to admin users.
“”"

意思是 仅允许管理员用户访问 所以改写这个方法

Django中rest framework框架的十大组件流程及源码概述_第21张图片

随后在views.py里面去配置 订单的权限及认证的组件配置

# 导入的这个负责 认证
# 在 我的应用中从 我的组件包中的 auth 导入MyAuthtication类
from myapp.myutils.auth import MyAuthtication

# 导入的这个负责 权限
# 在 我的应用中从 我的组件包中的 permission 导入SVIPPermission类
from myapp.myutils.permission import SVIPPermission

然后 加入这个 就会加入组件包 来实现 认证 权限两个功能

Django中rest framework框架的十大组件流程及源码概述_第22张图片

或者我们在settings.py设置全局组件配置 权限 首先我们要找到源码来写入 这个配置的功能

在class类里面的(APIView)在pycharm按住ctrl点击APIView,然后向下翻找到

Django中rest framework框架的十大组件流程及源码概述_第23张图片

DEFAULT_PERMISSION_CLASSES 这个就代表配置 settings.py需要设置的方法 [这里写的是方法类的路径]

Django中rest framework框架的十大组件流程及源码概述_第24张图片

然后在view.py订单视图中 写入

class OrderView(APIView):
    """
    订单相关业务
    """
    authentication_classes = []
    permission_classes = []

然后我们用postman进行 实际测试验证

先找到数据库表中 user_type类型为svip的 因为如果是1或者2类型就无法访问

Django中rest framework框架的十大组件流程及源码概述_第25张图片

然后进行登录获取token

Django中rest framework框架的十大组件流程及源码概述_第26张图片

将获取到的token放在一个文本里 然后在重新打开一个postman的页面 打开配置的路由找到路径 复制这个路径在这里插入图片描述

将这个链接 粘贴到postman 新页面?token=你的文本里面的token

http://127.0.0.1:8000/api/v1/order/?token= 后面放你从文本复制的token

在postman进行验证 输入对的token 就可以获取到表单

Django中rest framework框架的十大组件流程及源码概述_第27张图片

输入错误token再次尝试 用户认证失败

Django中rest framework框架的十大组件流程及源码概述_第28张图片

在数据库找一个 user_type类型为2 的进行登录 获取token 进行获取订单看看是什么结果

Django中rest framework框架的十大组件流程及源码概述_第29张图片

将token输入告诉 无权限访问 那么功能都可以实现

Django中rest framework框架的十大组件流程及源码概述_第30张图片

------------------------------------------------------------------------------------

rest framework的第三组件

限流:

限流就是限制访问频率或者次数

首先 在我的应用组件包创建限流 throttle.py文件 在里面设置我们的限流方法

# 从rest_framework.throttling 导入BaseThrottle方法
from rest_framework.throttling import BaseThrottle
# 导入时间
import time
# 设置一个空字典
HISTORY_DICT = {}
# 写MyThrottle类继承 BaseThrottle方法
class MyThrottle(BaseThrottle):
	# 初始化self.history
    def __init__(self):
        self.history = None
	# 重写allow_request方法
    def allow_request(self, request, view):
        # 获取 (META["REMOTE_ADDR"])当前用户的ip
        ip_addr = request._request.META["REMOTE_ADDR"]
        # 获取当前时间
        ctime = time.time()
        # 如果 用户当前的ip 不在空字典中
        if ip_addr not in HISTORY_DICT:
        	# 那么就把当前ip赋予一个 现在的时间
            HISTORY_DICT[ip_addr] = [ctime, ]
            return True
        # 如果这条ip在空字典中
        history = HISTORY_DICT[ip_addr]
		# 初始化的self.history
        self.history = history
        # 在空字典的ip 找到最后一个ip 是最早的时间那个 小于现在时间的60秒
        while history and history[-1] < ctime - 60:
            # 就删除最后一个
            history.pop()

        # 如果ip记录 小于3次
        if len(history) < 3:
        	# 就添加ip 并赋予现在的时间
            history.insert(0, ctime)
            return True

        # 如果访问返回True表示可以继续往下走,False被限制访问
        return False

    def wait(self):
        # 这里是应该返回 剩余的 等待时间
        # 要先拿到历史记录
        # 当前时间
        ctime = time.time()
        return 60 - (ctime - self.history[-1])

我们重写了def allow_request(self, request, view):方法 我们可以看看源码是怎样写的

首先点击 self.dispatch() 找到 self.initial(request,*args,**kwargs)点击 进入

Django中rest framework框架的十大组件流程及源码概述_第31张图片

然后点击 代表限流的组件方法

Django中rest framework框架的十大组件流程及源码概述_第32张图片

在这里会找到封装的allow_request 点击它 选择第三个

Django中rest framework框架的十大组件流程及源码概述_第33张图片

这里就会出现allow_request源码的方法 和 wait源码的方法

Django中rest framework框架的十大组件流程及源码概述_第34张图片
Django中rest framework框架的十大组件流程及源码概述_第35张图片

我们开始在views.py设置 一个类来测试我们书写的代码逻辑是否正确

# 在我的组件包导入 MyThrottle方法
from myapp.myutils.throttle import MyThrottle


class StudentView(APIView):
    authentication_classes = [MyAuthtication]
    permission_classes = [SVIPPermission]

    # 开启这个代表自己设置的限流
    throttle_classes = [MyThrottle]

	
    def get(self, request, *args, **kwargs):
    	# 获取当前的ip
        ip = request.META.get('REMOTE_ADDR')
        # 并返回当前的ip
        return JsonResponse({'ip': ip})

也可以在settings.py全局设置组件

Django中rest framework框架的十大组件流程及源码概述_第36张图片

怎么找到它呢 ?

在class类里面的(APIView)在pycharm按住ctrl点击APIView,然后向下翻找到

Django中rest framework框架的十大组件流程及源码概述_第37张图片

设置urls.py接口

Django中rest framework框架的十大组件流程及源码概述_第38张图片

我们在postman中 先登录 认证 然后获取三次 等待60秒再次获取 是否正常

http://127.0.0.1:8000/api/v1/thor/?token=写入你当前获取的token

Django中rest framework框架的十大组件流程及源码概述_第39张图片
Django中rest framework框架的十大组件流程及源码概述_第40张图片
Django中rest framework框架的十大组件流程及源码概述_第41张图片
Django中rest framework框架的十大组件流程及源码概述_第42张图片

一切正常

在工具包的throttle.py里面继续写入

还有一种方法将ip放入缓存 需求是 登录订单一天访问一次 其他登录 一天访问三次

# 从rest_framework.throttling 导入SimpleRateThrottle方法
from rest_framework.throttling import SimpleRateThrottle

# 如果我们要使用 内置的限流类
# SimpleRateThrottle 内置的 写好的 限流组件
class MyThrottle2(SimpleRateThrottle):
    scope = "myscope"

    # 缓存配置
    def get_cache_key(self, request, view):
        return self.get_ident(request)

# 订单登录
class UserThrottle(SimpleRateThrottle):
    scope = "user_scope"

    def get_cache_key(self, request, view):
        return request.user.username

settings.py全局设置

Django中rest framework框架的十大组件流程及源码概述_第43张图片

这个配置从哪里来? 在这里向上翻

Django中rest framework框架的十大组件流程及源码概述_第44张图片

找到这个 这里是相关的一些配置

Django中rest framework框架的十大组件流程及源码概述_第45张图片

这个是使用的方法

Django中rest framework框架的十大组件流程及源码概述_第46张图片

进入订单登录查看是否 一天只能登录一次

Django中rest framework框架的十大组件流程及源码概述_第47张图片
Django中rest framework框架的十大组件流程及源码概述_第48张图片

一次 限制

在这里插入图片描述

认证登录 每分钟只能访问三次

Django中rest framework框架的十大组件流程及源码概述_第49张图片
Django中rest framework框架的十大组件流程及源码概述_第50张图片
Django中rest framework框架的十大组件流程及源码概述_第51张图片
Django中rest framework框架的十大组件流程及源码概述_第52张图片

三次 限制

在这里插入图片描述

------------------------------------------------------------------------------------

rest framework的第四组件

版本:

在这里插入图片描述

一种是原生的源码

# QueryParameterVersioning点击这个里面会有个这种方法
from rest_framework.versioning import QueryParameterVersioning

点击这个

Django中rest framework框架的十大组件流程及源码概述_第53张图片
Django中rest framework框架的十大组件流程及源码概述_第54张图片

含义

Django中rest framework框架的十大组件流程及源码概述_第55张图片
Django中rest framework框架的十大组件流程及源码概述_第56张图片
Django中rest framework框架的十大组件流程及源码概述_第57张图片

点击这个选择第三个

Django中rest framework框架的十大组件流程及源码概述_第58张图片
Django中rest framework框架的十大组件流程及源码概述_第59张图片
在这里插入图片描述

复制这个到settings.py进行全局配置

Django中rest framework框架的十大组件流程及源码概述_第60张图片
在这里插入图片描述

REST_FRAMEWORK = {
    "DEFAULT_VERSION": "v1",# 默认版本
    "ALLOWED_VERSIONS": ["v1", "v2"],# 被允许访问的版本

}

另一种方法

# 从rest_framework.versioning 导入 URLPathVersioning
from rest_framework.versioning import URLPathVersioning

# 设计一个类
class UsersView(APIView):
    versioning_class = URLPathVersioning  # 调入版本这个方法

    def get(self, request, *args, **kwargs):
    	# 获取版本
        v = request.version
        u1 = request.versioning_scheme.reverse(viewname="user",request=request)
        print(u1)
        return HttpResponse(v)

点击这个URLPathVersioning看源码

from rest_framework.versioning import URLPathVersioning

继承的是这个方法点击

Django中rest framework框架的十大组件流程及源码概述_第61张图片

鼠标滚动找到复制这个 放到urls.py路由中Django中rest framework框架的十大组件流程及源码概述_第62张图片

from django.conf.urls import url
from .views import UsersView


# http://127.0.0.1:8000/api/v1/users/ # 推荐
# http://127.0.0.1:8000/api/users/?verison=v1 第一种获取版本的方式 也有公司这种

urlpatterns = [
    # url(r'^users/$', UsersView.as_view())
    # 并修改成这种形似
    url(r'^(?P[v1|v2]+)/users/', UsersView.as_view())
]

反向生成URL

Django中rest framework框架的十大组件流程及源码概述_第63张图片

增加一个name参数

url(r'^(?P[v1|v2]+)/users/', views.UsersView.as_view(),name='user')

在postman运行

http://127.0.0.1:8000/api/v1/users/

Django中rest framework框架的十大组件流程及源码概述_第64张图片

反向url

在这里插入图片描述

------------------------------------------------------------------------------------

rest framework的第五组件

解析器(parser):

Django中rest framework框架的十大组件流程及源码概述_第65张图片
Django中rest framework框架的十大组件流程及源码概述_第66张图片
Django中rest framework框架的十大组件流程及源码概述_第67张图片Django中rest framework框架的十大组件流程及源码概述_第68张图片

Django中rest framework框架的十大组件流程及源码概述_第69张图片
Django中rest framework框架的十大组件流程及源码概述_第70张图片
Django中rest framework框架的十大组件流程及源码概述_第71张图片
Django中rest framework框架的十大组件流程及源码概述_第72张图片
Django中rest framework框架的十大组件流程及源码概述_第73张图片
Django中rest framework框架的十大组件流程及源码概述_第74张图片

序列化:

序列化有两大功能:请求数据的验证,对queryset的序列化

创建URL
url(r'^(?P[v1|v2]+)/roles/$', views.RolesView.as_view()),
编写视图(方法1)
class RolesView(APIView): # 创建类 继承APIView
	def get(self,request,*args,**kwargs): # 发起get请求
	roles = models.Role.objects.all().values('id','title') # 获取Role模型里面的id和title字段
	roles = list(roles) # 将 获取的数据转换成列表
	import json # 导入json
	ret = json.dumps(roles) # 将queryset数据转换成 json数据
	return HttpResponse(ret) # 利用HttpResponse 页面展示出来

Django中rest framework框架的十大组件流程及源码概述_第75张图片

DRF序列化:

from rest_framework import serializers

class RolesSerializer(serializers,Serializer):
	# 变量名要和数据的字段一致
	title = serializers.CharField()

class RolesView(APIView):
   def get(self, request, *args, **kwargs):
       roles = models.Role.objects.all()
       ser = RolesSerializer(instance=roles, many=True) # 调用RolesSerializer类 instance=roles实例获取到的数据 many=True
       import json
       return HttpResponse(json.dumps(ser.data)) # 数据都在data中

自定义序列化:

创建URL
url(r'^(?P[v1|v2]+)/userinfo/$', views.UserInfoView.as_view())
创建视图
class UserInfoSerializer(serializers.Serializer):
   username = serializers.CharField()
   password = serializers.CharField()
   
class UserInfoView(APIView):
   def get(self, request, *args, **kwargs):
       users = models.UserInfo.objects.all()
       ser = UserInfoSerializer(users, many=True)
       import json
       return HttpResponse(json.dumps(ser.data))

假设我需要把用户类型也显示出来

class UserInfoSerializer(serializers.Serializer):
   user_type = serializers.IntegerField()

Django中rest framework框架的十大组件流程及源码概述_第76张图片

显示具体choice中文
class UserInfoSerializer(serializers.Serializer):
   xxxx = serializers.IntegerField(source='user_type') # 将user_type字段显示
   oooo = serializers.CharField(source='get_user_type_display') # 获取user_type字段的中文
   username = serializers.CharField()
   password = serializers.CharField()

Django中rest framework框架的十大组件流程及源码概述_第77张图片

序列化文章的整个表

from django.db import models


# Create your models here.
class UserGroup(models.Model):
    """用户组模型"""
    title = models.CharField(max_length=32, verbose_name="用户组名")


class Role(models.Model):
    """角色模型"""
    title = models.CharField(max_length=32, verbose_name="角色名")


class UserInfo(models.Model):
    user_type_choices = (
        (1, "普通用户"),
        (2, "VIP"),
        (3, "SVIP")
    )
    user_type = models.IntegerField(choices=user_type_choices, verbose_name="用户类型")
    username = models.CharField(max_length=32, unique=True)
    password = models.CharField(max_length=256)
    # 外键关系的显示 一对多的外键关系的显示
    group = models.ForeignKey(UserGroup, verbose_name="所属用户组")
    # 多对多关系的序列化
    roles = models.ManyToManyField(Role)


class UserToken(models.Model):
    user = models.OneToOneField(UserInfo)
    token = models.CharField(max_length=256)
显示指定内容 获取一对多关系
class UserInfoSerializer(serializers.Serializer):
 
	# 获取一对多group表下的id 和 title
   gp = serializers.CharField(source="group.id")
   gp2 = serializers.CharField(source="group.title")

Django中rest framework框架的十大组件流程及源码概述_第78张图片

自定义显示字段Django中rest framework框架的十大组件流程及源码概述_第79张图片Django中rest framework框架的十大组件流程及源码概述_第80张图片

填入数据库

class UserInfoSerializer(serializers.Serializer):
   xxxx = serializers.IntegerField(source='user_type')
   oooo = serializers.CharField(source='get_user_type_display')
   username = serializers.CharField()
   password = serializers.CharField()
   gp = serializers.CharField(source="group.id")
   gp2 = serializers.CharField(source="group.title")
   rls = serializers.SerializerMethodField()  # 自定义显示
   
	def get_rls(self, row):  # row当前行的对象
       role_obj_list = row.roles.all()       
       ret = []
       for item in role_obj_list:
           ret.append({
               'id': item.id,
               'title': item.title
        })
       return ret

Django中rest framework框架的十大组件流程及源码概述_第81张图片

一般在序列化中我们都继承这个 ModelSerializer 它继承的是Serializer 所以方便使用减少代码

class UserInfoSerializer2(serializers.ModelSerializer):
    user_type = serializers.CharField(source='get_user_type_display')
    group = serializers.CharField(source="group.title")
    rls = serializers.SerializerMethodField()  # 自定义显示
    def get_rls(self, row):  # row当前行的对象
        role_obj_list = row.roles.all()

        ret = []
        for item in role_obj_list:
            ret.append({
                'id': item.id,
                'title': item.title
            })

        return ret
    class Meta:
        model= models.UserInfo #"username","password"是UserInfo表里的 "user_type",'group','rls' 是上面获取的字段
        fields = ("username","password","user_type",'group','rls')

class UserInfoView(APIView):
    def get(self, request, *args, **kwargs):
        # 1、要从数据库里面 取出数据  罗列出所有用户名和密码
        users = models.UserInfo.objects.all()
        # 2、进行序列化 (序列化的组件)
        ser = UserInfoSerializer2(instance=users, many=True)
        import json
        return HttpResponse(json.dumps(ser.data))

Django中rest framework框架的十大组件流程及源码概述_第82张图片

DRF序列化深度控制

# 深度控制  解决了  正常 1对多 多对多
class UserInfoSerializer3(serializers.ModelSerializer):
    user_type = serializers.CharField(source='get_user_type_display')
    class Meta:
        model = models.UserInfo
        fields = "__all__"
        # 主要这个就是深度控制
        depth = 1 # 深度控制,数字越大  取层数越多  但是 效率越低


class UserInfoView(APIView):
    def get(self, request, *args, **kwargs):
        # 1、要从数据库里面 取出数据  罗列出所有用户名和密码
        users = models.UserInfo.objects.all()
        # 2、进行序列化 (序列化的组件)
        ser = UserInfoSerializer3(instance=users, many=True)
        import json
        return HttpResponse(json.dumps(ser.data))



"""
深度控制 1句话  封装度越高(1句话)  能实现的功能就越固定 灵活性 定制性就差

"""

Django中rest framework框架的十大组件流程及源码概述_第83张图片

序列化生成hypermed(给url)

编写URL

url(r'^(?P[v1|v2]+)/group/(?P\d+)/$', views.GroupfoView.as_view(),name='gp')

查看组的详细

class GroupSerializer(serializers.ModelSerializer):
	class Meta:
		model = models.UserGroup
		fields = "__all__"
class GroupfoView(APIView):
	def get(self, request, *args, **kwargs):
		pk = kwargs.get('pk')
		obj = models.UserGroup.objects.filter(pk=pk).first()
		import json
		ser = GroupSerializer(instance=obj, many=False)
		ret = json.dumps(ser.data)
		return HttpResponse(ret)

改进

class UserInfoView(APIView):
	def get(self, request, *args, **kwargs):
	...
	ser = UserInfoSerializer(users, many=True,context={'request': request})
	...
class UserInfoSerializer(serializers.ModelSerializer):
	# 帮我们反向生成URL,相当于我们给了group一个id,它帮我们反向生成一个url
	group = serializers.HyperlinkedIdentityField(view_name='gp')
class Meta:
	model = models.UserInfo
	fields = "__all__"
	depth = 0

Django中rest framework框架的十大组件流程及源码概述_第84张图片

序列化验证

编写URL

url(r'^(?P[v1|v2]+)/usergroup/$', views.UserGroupView.as_view(), name='ugp'),
编写视图
class UserGroupView(APIView):
	def post(self, request, *args, **kwargs):
		print(request.data)
		return HttpResponse("提交数据")
post提交数据

在这里插入图片描述
Django中rest framework框架的十大组件流程及源码概述_第85张图片
Django中rest framework框架的十大组件流程及源码概述_第86张图片

Django中rest framework框架的十大组件流程及源码概述_第87张图片

Django中rest framework框架的十大组件流程及源码概述_第88张图片

你可能感兴趣的:(rest,framework)