19. drf相关基础

一、drf 内容概况

1 django-rest-framework:drf,是一个app
    ​ 1-drf-drf入门规范
    ​ 2-drf-序列化组件
    ​ 3-drf-请求与响应
    ​ 4-drf-视图组件
    ​ 5-drf-路由组件
    ​ 6-drf-认证权限频率
    ​ 7-drf-过滤排序分页异常处理
    ​ 8-drf-自动生成接口文档
    ​ 9-drf-JWT认证:token
    ​ 10-drf-Xadmin的使用:第三方写的,比admin好看的后台管理
    ​ 11-Book系列多表群操作
    ​ 12-RBAC-基于角色的访问控制
    django缓存,信号,跨域(cors:跨域资源共享)
2 Vue:前端js框架
3 前后端分离项目:路飞学城

二、web开发模式

1、前后端混合开发(模板语言:DTL),处理很多前端问题
2、前后端分离:前端是一个项目,后端是一个项目,测试时联调——全栈开发
3、前端:不仅仅指 web前端,还有移动端,小程序等
	-web:vue,react,html+css+jq
    -移动端:ios(object c,swift),安卓(java,Kotlin)
    -小程序:微信自己把js,html,css,封装了一下
    
    -发展到现在:大前端概念
    	-flutter:Dart
        -uni-app:vue框架
            
4 后端只需要返回json格式字符串即可

前后端混合开发:

前后端混合开发

前后端分离开发:

前后端分离

三、API接口

1 访问/books/--->返回json格式数据--->/books/就是一个api接口
2 开放的api接口
	-微博
    -百度
    
3 api文档(前端开放看的)

4 典型的api接口
	-https://api.weibo.com/2/statuses/home_timeline.json

四、postman的使用

1 后端开放完,使用postman测试接口(api接口)
2 使用postman导出和导入测试接口
3 公司测试平台

五、drf的安装

1、框架简介:
	djangorestframework:是基于django的app,只能在django上使用
2、安装:
	pip3 install djangorestframework
	(默认安装最新版)

六、cbv源码回顾

# drf:APIView的源码分析

    def as_view(cls, **initkwargs):
        # 这句话执行完成返回 view闭包函数的内存地址
        view = super().as_view(**initkwargs) # 调用父类(View)的as_view
        view.cls = cls
        view.initkwargs = initkwargs
        view=csrf_exempt(view)  # 局部禁用csrf
        return view

 # 装饰器的使用方式
@csrf_exempt   ====>相当于:view=csrf_exempt(view)
def view():
    pass

# 请求来了,会执行上面返回的view()---->self.dispatch(APIView的dispatch)


# APIView的dispatch方法源码分析:
    def dispatch(self, request, *args, **kwargs):
		# 把原生的request,封装进新的Request对象(drf的Request)
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request

        try:
        	# 重点!(频率,认证,权限。。。)
            self.initial(request, *args, **kwargs)

            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
			# 这个request是新的request,是drf中Request对象
            # response是原生response
            response = handler(request, *args, **kwargs)

        except Exception as exc:
            # 全局异常
            response = self.handle_exception(exc)
		# 把原生response包装了一下
        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response

七、RESTful规范

1 REST全称
	Representational State Transfer:表征性状态转移
    是一种定义web API接口的设计风格,尤其适用于前后端分离的应用模式中
2 Web API接口的设计风格,尤其适用于前后端分离的应用模式中
3 与语言,平台无关,任何框架都可以写出符合restful规范的api接口
4 规范:10-1  数据的安全保障:url链接一般都采用https协议进行传输
    
    -2  接口特征表现:api关键字标识
    	-https://api.baidu.com/books/
        -https://www.baidu.com/api/books/
            
    -3 多版本共存:url链接中标识接口版本
    	-https://api.baidu.com/v1/books/
		-https://api.baidu.com/v2/books/
            
    -4 数据即是资源,均使用名词(可复数)***********
    	-接口一般都是完成前后台数据的交互,交互的数据我们称之为资源
        -一般提倡用资源的复数形式,不要使用动词
        -查询所有图书
        	-https://api.baidu.com/books/
            -https://api.baidu.com/get_all_books/ # 错误示范
            -https://api.baidu.com/delete_user    # 错误的示范
            -https://api.baidu.com/user/          # 删除用户的示例(删除与获取都使用这一个url,区别在于请求方式不同)
                
   -5 资源操作由请求方式决定:
		https://api.baidu.com/books       - get请求:获取所有书
        https://api.baidu.com/books/1     - get请求:获取主键为1的书
        https://api.baidu.com/books       - post请求:新增一本书书
        https://api.baidu.com/books/1     - put请求:整体修改主键为1的书
        https://api.baidu.com/books/1     - patch请求:局部修改主键为1的书
        https://api.baidu.com/books/1     - delete请求:删除主键为1的书
            
   -6 过滤,通过在url上传参的形式传递搜索条件
        https://api.example.com/v1/zoos?limit=10           		:指定返回记录的数量
        https://api.example.com/v1/zoos?offset=10&limit=3		:指定返回记录的开始位置
        https://api.example.com/v1/zoos?page=2&per_page=100		:指定第几页,以及每页的记录数
        https://api.example.com/v1/zoos?sortby=name&order=asc	:指定返回结果按照哪个属性排序,以及排序顺序
        https://api.example.com/v1/zoos?animal_type_id=1		:指定筛选条件
            
   -7  响应状态码
		-返回数据中带状态码
		-{'code':100}
        
   -8 返回结果中带错误信息
		-{'code':100, 'msg':'因为xx原因失败'}
    
   -9 返回结果,该符合以下规范
		GET /collection:返回资源对象的列表(数组)
        GET /collection/resource:返回单个资源对象(字典)
        POST /collection:返回新生成的资源对象 (新增后的对象字典)
        PUT /collection/resource:返回完整的资源对象 (修改后的对象字典)
        PATCH /collection/resource:返回完整的资源对象 (修改后的对象字典)
        DELETE /collection/resource:返回一个空文档   ()
        
   -10 返回的数据中带链接地址
		-查询id1的图书接口,返回结果示例
    	{"code": 100,
         "msg": '成功',
         "result":
             {"title": "红楼梦",
              "price": 12.3,
              "publish": "https://127.0.0.1/api/v1/publish/3"
             }
        }

八、APIview源码分析

1 APIview的as_view
	-内部还是执行了View的闭包函数view
    -使用装饰器禁用掉了csrf
    -一切皆对象,函数也是对象  函数地址.name=lqz
    
2 原生View类中的as_view中的闭包函数view
	-本质执行了self.dispatch(request, *args, **kwargs),执行的是APIView的dispatch
    
3 APIView的dispatch:
    def dispatch(self, request, *args, **kwargs):
        # DRF的Request类的对象,内部有request._request,是原生request
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request

        try:
            self.initial(request, *args, **kwargs)
            '''
            #认证,权限,频率
            self.perform_authentication(request)
        	self.check_permissions(request)
        	self.check_throttles(request)
            '''
            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)
		# 把视图函数(类)返回的response,又包装了一下
        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response

九、Request类分析

1 Request类:对象属性
	-request._request :原生request
    -request.data     : post请求提交的数据(urlencoded,json,formdata)
    -request.user     :不是原生的user了
    -request.query_params :原生的request.GET,为了遵循restful规范
    -requset.FILES    :新的
    -重写了__getattr__,新的request.原来所有的属性和方法,都能直接拿到
        def __getattr__(self, attr):
            return getattr(self._request, attr)

十、序列化组件介绍

# 作用:
    1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串
    	Book对象--序列化器--->字典--->通过drf:Response--->json格式字符串--->传给前端
    2. 反序列化,把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转成模型
    	json格式数据--->drf:Request--->字典--->序列化器--->Book对象
    3. 反序列化,完成数据校验功能

十一、序列化组件简单使用

1、序列化的使用步骤

	-写一个序列化类继承serializers.Serializer
    -在类中写要序列化的字段
    -在视图类中,实例化得到一个序列化类的对象,把要序列化的数据传入
    	ser=BookSerializer(instance=res,many=True)
    -得到字典
    	ser.data就是序列化后的字典

2、代码实现

新建一个文件——serializer.py:

from rest_framework import serializers
class BookSerializer(serializers.Serializer):
    # 类中写要序列化的字段
    id=serializers.IntegerField()
    # 也可以写id=serializers.CharField()
    title=serializers.CharField(max_length=32)
    price=serializers.DecimalField(max_digits=5, decimal_places=2)
    # 不需要序列化的字段可以不写
    # publish=serializers.CharField(max_length=32)

models.py

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish = models.CharField(max_length=32)

views.py

from rest_framework.request import Request
from django.views import View
from rest_framework.views import APIView
from rest_framework.response import Response
from app01 import models
from app01.serializer import BookSerializer

class Book(APIView):
    def get(self,request,*args,**kwargs):

        res=models.Book.objects.all()
        # 借助序列化器
        # 如果是queryset对象,就加上many=True
        # 如果是单个对象,就不写
        ser=BookSerializer(instance=res,many=True)
        # 通过序列化器得到的字典
        # ser.data
        print(ser.data)
        return Response(ser.data)

urls.py

path('books/', views.Book.as_view()),

PS:需要注册rest_framework

INSTALLED_APPS = [
    ...
    'rest_framework',
]

十二、序列化类字段类型和字段参数

# 字段类型(常用的如下)
	-IntegerField
    -CharField
    -DecimalField
    -DateTimeField
    -...(跟models中大差不差)
    
# 常用字段参数
	-选项参数
        max_length	最大长度
        min_lenght	最小长度
        allow_blank	是否允许为空
        trim_whitespace	是否截断空白字符
        max_value	最小值
        min_value	最大值
    
    -通用参数
    	#重点
        read_only	表明该字段仅用于序列化输出,默认False
        write_only	表明该字段仅用于反序列化输入,默认False
        
        # 掌握
        required	表明该字段在反序列化时必须输入,默认True
        default	    反序列化时使用的默认值
        allow_null	表明该字段是否允许传入None,默认False
        
        # 了解
        validators	该字段使用的验证器
        error_messages	包含错误编号与错误信息的字典

十三、序列化器的保存功能

# 如果序列化类继承的是Serializer,必须重写create方法
# 使用方式
	-视图类
     def post(self, request):
        print(request.data)
        ser = BookSerializer(data=request.data)
        if ser.is_valid():
            ser.save()  # 保存到数据库中
            return Response(ser.data)
        else:
            # 没有校验通过的错误信息
            return Response(ser.errors)
    
    -序列化类  
    class BookSerializer(serializers.Serializer):
        ...
		 # 要重写create
        def create(self, validated_data):
            res=models.Book.objects.create(**validated_data)
            print(res)
            return res

十四、序列化器的字段校验功能

# 三种方式
	-字段自己的校验规则(max_length...-validators的校验
        publish = serializers.CharField(max_length=32,validators=[check,])

     	def check(data):
            if len(data)>10:
                raise ValidationError('最长不能超过10')
            else:
                return data
    
    -局部和全局钩子
    # 局部钩子,validate_字段名,需要带一个data,data就是该字段的数据
    def validate_title(self, data):
        if data.startswith('sb'):
            raise ValidationError('不能以sb开头')
        else:
            return data
    
    # 全局钩子
    def validate(self, attrs):
        title=attrs.get('title')
        publish=attrs.get('publish')
        if title==publish:
            raise ValidationError('书名不能跟出版社同名')
        else:
            return attrs

十五、read_only和write_only属性

#    read_only	表明该字段仅用于序列化输出,默认False
#    write_only	表明该字段仅用于反序列化输入,默认False
    
    
    class BookSerializer(serializers.Serializer):
        
        id = serializers.IntegerField(required=False)
        title = serializers.CharField(max_length=32,min_length=2,read_only=True)
        price = serializers.DecimalField(max_digits=5, decimal_places=2)
        # 序列化的时候看不到
        publish = serializers.CharField(max_length=32,validators=[check,],write_only=True)    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值