django框架--drf入门(一)

发布时间:2023年12月19日

CBV流程

想学好django框架–drf就必须先进行CBV的源码解读

CBV(class base views) 基于类的视图,就是在视图里使用类处理请求。

在这里插入图片描述
当路由匹配到如上user的时候,执行其后面的views.UserView中的as_view方法。
urls.py 文件

urlpatterns = [
    path("users/", views.Userview.as_view()),
]

views.py 文件

from rest_framework.views import APIView
class UserView(APIView):
    pass

我们可以看到在我们自己写的类UserView中并没有as_view方法,但它继承于APIView,我们可以在1中看到,APIView的as_view继承了父类View(也就是CBV模式下最先学习的基类)的全部功能,此时我们获得了原本的view函数。在1的retrun中我们看到了csrf_exempt(view),这一步的过程其实就像我们以前去掉csrf_token认证引入的装饰器一样,用于去除csrf_token认证。我们以后选择用jwt进行认证。

主要还是通过父类 View 提供的一个静态方法 as_view() ,as_view 方法是基于类的外部接口, 他返回一个视图函数,调用后请求会传递给 dispatch 方法,dispatch 方法再根据不同请求来处理不同的方法。

    @classonlymethod
    def as_view(cls, **initkwargs):
      ..........
        def view(request, *args, **kwargs):
        ...........
            return self.dispatch(request, *args, **kwargs) #关键这句
          .........
        return view
    def dispatch(self, 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
        return handler(request, *args, **kwargs)
        

以上是django的View的as_view方法 所以以上使用getattr函数用来获取一个对象的属性值或方法

进入drf框架的site-packages\rest_framework\views.py文件下

class APIView(View):
   .....

我们与View基类的dispatch做对比,看到它除了与基类同样运用反射获取请求方式外,其前后还分别对request和response进行了封装。

drf中重写了 as_view 和dispatch方法,其实就是在原来django的功能基础上添加了一些功能

例如:
as_view,免除了csrf 验证,一般前后端分离不会使用csrf token认证(后期会使用jwt认证)。

dispatch,内部添加了 版本处理、认证、权限、访问频率限制等诸多功能(后期逐一讲解)。

drf与django的关系

Django REST framework是一个建立在Django基础之上的Web 应用开发框架,可以快速的开发REST API接口应用。在REST framework中,提供了序列化器Serialzier的定义,可以帮助我们简化序列化与反序列化的过程,不仅如此,还提供丰富的类视图、扩展类、视图集来简化视图的编写工作。REST framework还提供了认证、权限、限流、过滤、分页、接口文档等功能支持。REST framework提供了一个API 的Web可视化界面来方便查看测试接口。

django开发项目时,视图中的request是 django.core.handlers.wsgi.WSGIRequest 类的对象

# Django FBV
def index(request):
	request.method
	request.POST
	request.GET
	request.body
 
# Django CBV
from django.views import View
class UserView(View):
	def get(self,request):
        request.method
        request.POST
        request.GET
        request.body

在使用drf框架时,视图中的request是rest_framework.request.Request类的对象,其是又对django的request进行了一次封装,包含了除django原request对象以外,还包含其他后期会使用的其他对象。

from rest_framework.views import APIView
from rest_framework.response import Response
 
 
class UserView(APIView):
    def get(self, request, *args, **kwargs):
        return Response({"code": 1000, "data": "xxx"})
 
    def post(self, request, *args, **kwargs):
        return Response({"code": 1000, "data": "xxx"})

注:此时你看到的request,不再是曾经django中的request,而是又被封装了一层,内部包含:django的request、认证、解析器等。

在这里插入图片描述
在源码3中,大概是这样:有一个rest_framework.request.Request类,我们最后获得的request=Request(request,认证,分页…)

在文件site-packages\rest_framework\request.py中Request类

class Request:
   ......

我们从源码中可以看到,想要从请求中获取数据,有两种方法:

第一种:

request._request.method
request._request.GET
request._request.POST
request._request.body

第二种:

# 直接读取新request对象中的值,一般此处会对原始的数据进行一些处理,方便开发者在视图中使用。
request.query_params  # 内部本质上就是 request._request.GET
 
# 内部读取请求体中的数据,并进行处理,例如:请求者发来JSON格式,他的内部会对json字符串进行反序列化。
request.data 
        
# 通过 __getattr__ 去访问 request._request 中的值
request.method

request.method这样的可以通过反射获取,因此不需要改变。这里我们用request.query_params 替换了request.GET,request.data替换了request.POST.

值得一提的是,request.data会对收到的json格式自动进行反序列化。此外无论是content-type:
url-form-encoded还是content-type: application/json,该方法都可以获取到内容。

restful规范

在这里插入图片描述
RESTful是一种定义Web API接口的设计风格,尤其适用于前后端分离的应用模式中。

这种风格的理念认为后端开发任务就是提供数据的,对外提供的是数据资源的访问接口,所以在定义接口时,客户端访问的URL路径就表示这种要操作的数据资源。

事实上,我们可以使用任何一个框架都可以实现符合restful规范的API接口。

数据的安全保障

url链接一般都采用https协议进行传输

注:采用https协议,可以提高数据交互过程中的安全性

接口特征表现

用api关键字标识接口url:

https://api.baidu.com
https://www.baidu.com/api

注:看到api字眼,就代表该请求url链接是完成前后台数据交互的

多数据版本共存

在url链接中标识数据版本

https://api.baidu.com/v1
https://api.baidu.com/v2

注:url链接中的v1、v2就是不同数据版本的体现(只有在一种数据资源有多版本情况下)

数据即是资源,均使用名词(可复数)

接口一般都是完成前后台数据的交互,交互的数据我们称之为资源

https://api.baidu.com/users
https://api.baidu.com/books
https://api.baidu.com/book

注:一般提倡用资源的复数形式,在url链接中奖励不要出现操作资源的动词,错误示范:

https://api.baidu.com/delete-user

特殊的接口可以出现动词,因为这些接口一般没有一个明确的资源,或是动词就是接口的核心含义

https://api.baidu.com/place/search
https://api.baidu.com/login

资源操作由请求方式决定(method)

操作资源一般都会涉及到增删改查,我们提供请求方式来标识增删改查动作

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的书

过滤,通过在url上传参的形式传递搜索条件

https://api.example.com/v1/zoos?limit=10:指定返回记录的数量
https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置
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:指定筛选条件

响应状态码

1 正常响应

响应状态码2xx
200:常规请求
201:创建成功

2 重定向响应

响应状态码3xx
301:永久重定向
302:暂时重定向

3 客户端异常

响应状态码4xx
403:请求无权限
404:请求路径不存在
405:请求方法不存在

4 服务器异常

响应状态码5xx
500:服务器异常

错误处理,应返回错误信息,error当做key

{
    error: "无权限操作"
}

返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范

GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档

需要url请求的资源需要访问资源的请求链接

# Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么
{
  	"status": 0,
  	"msg": "ok",
  	"results":[
        {
            "name":"肯德基(罗餐厅)",
            "img": "https://image.baidu.com/kfc/001.png"
        }
      	...
		]
}

比较好的接口返回

# 响应数据要有状态码、状态信息以及数据本身
{
  	"status": 0,
  	"msg": "ok",
  	"results":[
        {
            "name":"肯德基(罗餐厅)",
            "location":{
                "lat":31.415354,
                "lng":121.357339
            },
            "address":"月罗路2380号",
            "province":"上海市",
            "city":"上海市",
            "area":"宝山区",
            "street_id":"339ed41ae1d6dc320a5cb37c",
            "telephone":"(021)56761006",
            "detail":1,
            "uid":"339ed41ae1d6dc320a5cb37c"
        }
      	...
		]
}
文章来源:https://blog.csdn.net/weixin_44143876/article/details/135053622
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。