文章目录
django restframework
- 快速上手
- 请求的封装
- 版本管理
- 认证
- 权限
- 限流
- 序列化
- 视图
- 条件搜索
- 分页
- 路由
- 解析器
1. 快速上手
-
安装
pip install djangorestframework==3.12.4
版本要求:djangorestframework==3.12.4 Python (3.5, 3.6, 3.7, 3.8, 3.9) Django (2.2, 3.0, 3.1) 版本要求:djangorestframework==3.11.2 Python (3.5, 3.6, 3.7, 3.8) Django (1.11, 2.0, 2.1, 2.2, 3.0)
-
配置,在settings.py中添加配置
INSTALLED_APPS = [ ... # 注册rest_framework(drf) 'rest_framework', ] # drf相关配置以后编写在这里 REST_FRAMEWORK = { }
-
URL和视图
# urls.py from django.urls import path from app01 import views urlpatterns = [ path('users/', views.UserView.as_view()), ]
# views.py 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"})
其实drf框架是在django基础进行的扩展,所以上述执行过得底层实现流程(同django的CBV):
drf中重写了 as_view
和dispatch
方法,其实就是在原来django的功能基础上添加了一些功能,例如:
as_view
,免除了csrf 验证,一般前后端分离不会使用csrf token认证(后期会使用jwt认证)。dispatch
,内部添加了 版本处理、认证、权限、访问频率限制等诸多功能(后期逐一讲解)。
在前后端不分离项目中要解决post,put,delete的crsf问题时:通常会在表单中加入
{% csrf_token %}
。
而如果是在前后端分离项目中就不可行了,此时就需要csrf_exempt装饰器:
2. 请求数据的封装
drf的request是 原来django的request与认证,解析等对象一起封装后的对象。
以前我们通过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):
# request,不再是django中的request,而是又被封装了一层,内部包含:django的request、认证、解析器等。
return Response({"code": 1000, "data": "xxx"})
def post(self, request, *args, **kwargs):
return Response({"code": 1000, "data": "xxx"})
对象 = (request, 其他数据)
# rest_framework.request.Request 类
class Request:
"""
Wrapper allowing to enhance a standard `HttpRequest` instance.
Kwargs:
- request(HttpRequest). The original request instance. (django中的request)
- parsers(list/tuple). The parsers to use for parsing the
request content.
- authenticators(list/tuple). The authenticators used to try
authenticating the request's user.
"""
def __init__(self, request, parsers=None, authenticators=None,negotiator=None, parser_context=None):
self._request = request
self.parsers = parsers or ()
self.authenticators = authenticators or ()
...
@property
def query_params(self):
"""
More semantically correct name for request.GET.
"""
return self._request.GET
@property
def data(self):
if not _hasattr(self, '_full_data'):
self._load_data_and_files()
return self._full_data
def __getattr__(self, attr):
try:
return getattr(self._request, attr) # self._request.method
except AttributeError:
return self.__getattribute__(attr)
所以,在使用drf框架开发时,视图中的request对象与原来的有些不同,例如:
from rest_framework.views import APIView
from rest_framework.response import Response
from django.views import View
from rest_framework.request import Request
class UserView(APIView):
def get(self, request, *args, **kwargs):
# 通过对象的嵌套直接找到原request,读取相关值
request._request.method
request._request.GET
request._request.POST
request._request.body
# 举例:
content-type: url-form-encoded
v1=123&v2=456&v3=999
django一旦读取到这个请求头之后,就会按照 {"v1":123,"v2":456,"v3":999}
content-type: application/json
{"v1":123,"v2":456}
request._request.POST
request._request.body
# 直接读取新request对象中的值,一般此处会对原始的数据进行一些处理,方便开发者在视图中使用。
request.query_params # 内部本质上就是 request._request.GET
request.data # 内部读取请求体中的数据,并进行处理,例如:请求者发来JSON格式,他的内部会对json字符串进行反序列化。
# 通过 __getattr__ 去访问 request._request 中的值
request.method
底层源码实现:
3. 版本管理
在restful规范中要去,后端的API中需要体现版本。
drf框架中支持5种版本的设置。(重点是前两种:参数传递,URL路径传递)
3.1 URL的GET参数传递(*)
# settings.py
REST_FRAMEWORK = {
"VERSION_PARAM": "v",
"DEFAULT_VERSION": "v1",
"ALLOWED_VERSIONS": ["v1", "v2", "v3"],
"DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.QueryParameterVersioning"
}
源码执行流程:
3.2 URL路径传递(*)
3.3 请求头传递
3.4 二级域名传递
在使用二级域名这种模式时需要先做两个配置:
-
域名需解析至IP,本地可以在hosts文件中添加
127.0.0.1 v1.wupeiqi.com 127.0.0.1 v2.wupeiqi.com
-
在django的settings.py配置文件中添加允许域名访问
ALLOWED_HOSTS = ["*"]
3.5 路由的namespace传递
以上就是drf中支持的5种版本管理的类的使用和配置。
全局配置
上述示例中,如果想要应用某种 版本 的形式,需要在每个视图类中定义类变量:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import QueryParameterVersioning
class UserView(APIView):
versioning_class = QueryParameterVersioning
...
如果你项目比较大,需要些很多的视图类,在每一个类中都写一遍会比较麻烦,所有drf中也支持了全局配置。
# settings.py
REST_FRAMEWORK = {
"DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.QueryParameterVersioning", # 处理版本的类的路径
"VERSION_PARAM": "version", # URL参数传参时的key,例如:xxxx?version=v1
"ALLOWED_VERSIONS": ["v1", "v2", "v3"], # 限制支持的版本,None表示无限制
"DEFAULT_VERSION": "v1", # 默认版本
}
底层源码实现
反向生成URL
使用drf是可以通过request.versioning_scheme.reverse(viewname, args, kwargs, request)来反向生成URL
在每个版本处理的类中还定义了reverse
方法,他是用来反向生成URL并携带相关的的版本信息用的,例如:
小结
以后使用drf开发后端API接口时:
- 创建django程序
- 安装drf框架
- 创建一个app专门来处理用户的请求
- 注册APP
- 设置版本
- 编写视图类
若有错误与不足请指出,关注DPT一起进步吧!!!