DRF框架基础

发布时间 2023-03-22 19:10:41作者: 阿丽米热

DRF框架基础

了解drf之前咱们安装一下该框架吧DRF安装与使用
本篇文章会详细介绍web开发模式、API接口及其接口测试工具、restful规范、还有经常分不清又很重要的序列化与反序列化的部分,初级交接触APIView、Request类。每个人对知识点的理解都会不一样,因此我会用自己的理解撰写一篇文章,这篇将会是我对学习的一个态度更是对自己的一个交代。那咱们开始吧!!嘿嘿嘿

一、web开发模式

在我们的web开发应用中,有两种开发模式,一是前后端不分离即全栈开发 咱们的BBS项目是典型例子。二是前后端分离,这种开发模式是我们以后的重点发展方向,因为研究的事件一旦变多了我们就会想办法解耦合,内容越细越精嘛,这就为什么会出现了后者,这种开发模式个人觉得整个过程非常舒服,每个人清楚的知道自己要干什么,自己的主要任务是什么。前端和后端分离之后,后端程序员只需要写接口也就是说与通过后端代码操作数据库,说白了就是对数据增删改查。接下来通过图片的方式更加直观的解释,会帮助到咱们的理解。

  • 前后端不分离:客户端看到的所有页面和后端关键逻辑都是由同一个服务端提供的
    image

  • 前后端分离:前端只负责页面且由独立服务端提供服务,后端只负责返回数据即可
    image

Python基础知识回顾---断言assert

​ 我们在分析源代码的时候会经常看到assert和try,因为就一个关键词节省了很多逻辑代码,其作用是声明其布尔值必须为真的判定,如果发生异常就说明表达示为假。可以理解assert断言语句为raise-if-not,用来测试表示式,其返回值为假,就会触发异常。

# 如果不用断言实现需求是如下
name = 'almira'
if name == 'almira':
    print('yep')
else:
    print('nope')
# 如果使用断言实现需求是如下
# 断定是就跑正常逻辑 如果不是就抛异常
assert name == 'almira'
print('keep it up')

二、API接口及测试

API接口定义
​ API接口即应用程序接口(Applicant Programming Interface),应用程序对外提供了一个操作数据的入口,这个入口的实现可以是通过FBV或CBV方式来完成、也可以是一个URL地址或一个网址。当客户端调用该入口时应用程序会执行相应的代码操作、给客户端完成对应的功能。这样可以减小前后端之间的合作成本,可以简单的理解为API接口是前后端之间信息交互的媒介。

接口测试工具

​ 我们脑海里肯定会出现一个疑问,浏览器就是天生的测试工具为嘛还要搞一个其他工具呢?兄dei那你就太天真来,浏览器只能解决get请求的测试需求,二程序员还要测试其他的请求,比如post、put、delete等等。这时候浏览器大哥也无可奈何了嘛!接口测试工具有以下6个:Poster、Postman、RESTClient、Fiddler、Jmeter、 WireMock。接口测试工具是用于测试系统组件间接口的工具,主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。同一类的软件使用以及底层原理都大差不差、举一反三,那我们本次学习那postman为例展开从软件下载到基本使用的操作过程。由于本姑娘喜欢分类与收纳,因此我把postman的安装与使用单独拎出来写了点击该地址既可以看到详细的过程。快戳我--->postman的安装与使用

三、restful十条规范

1.什么是restful规范呢?

这十条规范面试必问,一定要掌握

​ REST全称为Representational State Transfer即表述性状态转移,RESTful是一种专门为web开发而定义API接口的设计风格、尤其是适用于前后端分离的应用模式中。这种风格的理念是后端开发的任务就是提供数据、对外提供的是数据资源的访问接口、所以咋定义接口时客户端访问的URL路径就表示这种要操作的数据资源。而对于数据资源分别使用post、get、delete、update等请求动作来表达对数据的增删改查。RESTful规范是一种通用规范、不限制语言和开发框架的使用。因此、我们当然可以使用任何一门编程语言、任何框架都可以实现RESTful规范的API接口。

10个restful规范get一下呗!

  1. 为安全起见通常用https(http+ssl/tsl)协议
  2. 接口中要携带API标识如https://www.baidu.com/api/books
  3. 为满足多版本共存路径中带版本信息如https://www.baidu.com/api/v1/books
  4. 因为URL资源、均使用名词、尽量不要出现动词
  5. 而且资源的操作方式由请求方式决定
  6. 在请求地址中带过滤条件 在?号后面name=米热&price=11的形式
  7. 响应状态码有两种默认的和公司自定义的
  8. 返回数据中带错误信息
  9. 返回的结果一个规定规范但是公司有自己的格式
  10. 响应数据中带连接

四、序列化与反序列化

序列化与反序列化的核心:转换数据格式

​ API接口开发最核心最常见的一个代码编写过程就是序列化,所谓的序列化就是转换数据格式,其有两个阶段,一是序列化:把后端的数据编程字符串或者json数据提供给别人、二是反序列化:前端js提供的数据是json格式数据,对于Python而言json就是字符串需要反序列化成字典、将字典转换成模型对象,这样才能把数据保存到数据库中
image
序列化类的字段和参数

  • 序列化:查数据(单条多条)、后端数据库到前端页面、eg:登录接口
  • 反序列化:修改及存储数据、前端页面到后端数据库、eg:注册接口

五、DRF之请求request

request能够解析的前端传入的编码格式配置方法

方式一:局部配置

在APIView及其子类的视图类中配置具体操作步骤如下

# 1.需要先导入
from rest_framework.parsers import JSONParser,FormParser,MultiPartParser
# 2.在视图cbv里面写需要用的格式
class BookView(APIView):
    parser_classes = [JSONParser,]

方式二:全局配置

直接在配置文件里面改配置既可影响全局

# 不需要用的就注释掉既可
    REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        # 'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
        # 'rest_framework.parsers.MultiPartParser',
    ],
}

方式三:局部全局

局部配置方法和全局配置方法混着用
有个需求:全局配了一个某个视图类却想要三个怎么解决?
# 解决方法很简单
"""
直接在该视图类配置3个就可以
因为先从自身类找找不到去项目找再找不到就去drf默认配置找
"""

request类源码分析

  • 老的request:django.core.handlers.wsgi.WSGIRequest
  • 新的request:from rest_framework.request import Request

image

  • 新的request跟老的request用起来一样、新的取不到双下getattr就取老的
  • request.data无论是什么编码什么请求方式字典从body里面取数据取出来是字典
  • request.query_params就是原来的request._request.GET,请求携带的参数
  • request.FILES上传的文件从这里取

六、DRF之响应response

response响应编码格式

"""
drf是Django的一个APP因此当然要注册 切记哦
drf的响应如果使用浏览器和postman访问同一个接口返回的格式是不一样
因为drf做了个判断 如果是浏览器好看一些 如果是postman只要json数据
"""

方式一:局部配置

from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class BookView(APIView):
    renderer_classes=[JSONRenderer,]

方式二:全局配置

    REST_FRAMEWORK = {
      'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],
}

方式三:使用顺序

# 一般就用内置的即可
优先使用视图类中的配置,其次使用项目配置文件中的配置,最后使用内置的

response源码分析

# drf 的Response 源码分析
from rest_framework.response import Response
视图类的方法返回时,retrun Response ,走它的__init__,init中可以传什么参数
    
    
# Response init可以传的参数
    def __init__(self, 
                 data=None, 
                 status=None,
                 template_name=None, 
                 headers=None,
                 exception=False, 
                 content_type=None)
    
data:之前咱们写的ser.data  可以是字典或列表,字符串---》序列化后返回给前端---》前端在响应体中看到的就是这个 
status:http响应的状态码,默认是200,你可以改
drf在status包下,把所有http响应状态码都写了一遍,常量
from rest_framework.status import HTTP_200_OK
Response('dddd',status=status.HTTP_200_OK)        
template_name:了解即可,修改响应模板的样子,BrowsableAPIRenderer定死的样子,后期公司可以自己定制
headers:响应头,http响应的响应头
content_type :响应编码格式,一般不动

七、路由生成

1.普通路由写法
第一种是传统的纯手动写路由

from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', views.BookView.as_view()),
    path('books/<int:pk>/', views.BookDetailView.as_view()),

]

第二种是通过映射写路由

2.自动生成路由
第一种

# 第一步 导入模块以及路由类
from django.contrib import admin
from django.urls import path, include
from app01 import views
from rest_framework.routers import SimpleRouter, DefaultRouter

"""
DefaultRouter与SimpleRouter的区别:
DefaultRouter会多附带一个默认的API根视图
返回一个包含所有列表视图的超链接响应数据
"""

# 第二步 实例化得到对象
router = SimpleRouter()

# 第三步 注册(路径和视图类建立了关系,有几个视图就注册几次)
"""
第一个参数是路径,不要带 /
第二个参数是视图类
第三个参数是别名,一般跟路径相同
"""
router.register('user', views.UserView, 'user')  # /api/v1/user/login     post 请求

# 第四部:在这里添加以下
urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/v1/', include(router.urls)),

]

第二种

# 第一步 导入模块以及路由类
from django.contrib import admin
from django.urls import path, include
from app01 import views
from rest_framework.routers import SimpleRouter, DefaultRouter

# 第二步 实例化得到对象
router = SimpleRouter()

# 第三步 注册(路径和视图类建立了关系,有几个视图就注册几次)
"""
第一个参数是路径,不要带 /
第二个参数是视图类
第三个参数是别名,一般跟路径相同
"""
router.register('user', views.UserView, 'user')  # /api/v1/user/login     post 请求


urlpatterns = [
    path('admin/', admin.site.urls),
    # path('api/v1/', include(router.urls)),

]


# 第四步 两个列表相加 前提是要有上面的urlpatterns=[] [1,2,4] +  [6,7,8]=
urlpatterns += router.urls

自动生成路由和action装饰器结合使用

八、序列化器

from rest_framework import serializers
from .models import Book
from rest_framework.validators import ValidationError


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'
        extra_kwargs = {'name': {'max_length': 8},
                        'publish_detail': {'read_only': True},
                        'book_list': {'read_only': True},
                        'authors': {'write_only': True},
                        'publish': {'write_only': True},
                        }

        def validate_name(self, name):
            if name.startswith('中'):
                raise ValidationError('书名不能以中开头')
            else:
                return name

        def validate(self, attrs):
            if attrs.get('name') == attrs.get('publish'):
                raise ValidationError('书名和出版社名不能一样')
            else:
                return attrs

九、视图层类

详细的视图总结戳这里>>>: 视图层总结
以下是视图层思维导图
image

以下是接口编写演变过程
由简单到复杂
由繁杂到简介
有各种写法
满足程序员的各种编写雪球
请程序员尽情的DIY你们代码世界吧!!!