Django Rest Framework
安装
pip install djangorestframework
pip install markdown
pip install django-filter
pip install coreapi
pip install guardian
配置
from rest_framework.documentation import include_docs_urls
urlpatterns = [
# drf文档, title自定义
path('docs', include_docs_urls(title='标题')),
path('api-auth/', include('rest_framework.urls')),
]
INSTALLED_APPS = [
'rest_framework',
]
跨域配置
pip install django-cors-headers
- 在 settings.py 中添加
INSTALLED_APPS = [
'coreschema'
]
- 在 MIDDLEWARE 中添加
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware' # 放在第一行
]
- 在 settings.py 中添加变量
CORS_ORIGIN_ALLOW_ALL = True
drf - APIView
drf 中的 APIView 的调用流程
- APIView -> self.dispatch -> self.request = self.initialize_request 封装了 Django 的 HTTPRequest, 并添加了认证对象(AuthenticationClasses) -> self.initialize 对用户请求进行认证, 调用 self.request 的认证对象列表, 逐个认证(调用 authenticate) -> 如果认证出错, 则认证对象应该 raise 认证异常 -> drf 不会再走我们自己写的 get 等逻辑直接返回错误 401, 如果认证都通过则继续执行到用户的 get 等逻辑在返回 response
- 具体请看 APIView 中的 dispatch, 也很简单可以看懂
- 主要关注
- self.request = self.initialize_request
- self.initialize
- self.perform_authentications
- self.perform_permissions
drf 定义认证类
- 继承 BaseAuthentication, 该类只是一个接口, 要求子类实现 authenticate(request) 和 authenticate_header 方法, 这种方式是最常用的, 因为可以自定义
- authenticate 方法一个 tuple, 第一个为 user, 第二个为 token, 返回之后会被 APIView 放在 request 中
- authenticate_header 一般不用重写
- 返回值
- None: None 表示继续下一个认证
- 抛出异常, 表示认证失败, drf 会直接返回自己定义的 response
- (user, token): user 为用户名, token 为 token 字符串
- 使用
- 在 class 中定义 authenticate_classes list, 放入认证类
- 在 settings.py 中, 定义 REST_FRAMEWORK 配置全局
权限控制
- 和 drf 的认证类一样
- 继承 BasePermission, 实现 has_permission 方法, 如果有权限则返回 True, 否则 返回 False
访问频率控制
- 和 drf 的认证类一样
- 继承 BaseThrottle, 实现
allow_request
和 wait
方法, 其中 allow_request
要求返回 True 或者 False, 而 wait
返回字符串, 在返回给用户时提示还要有多久才能继续访问
解析器
- 在 django 和 drf 中解析器就是将 request 中的 body 接地刀 request 的 POST 中方便开发者获取, 我们一般不需要定义自己的解析器, drf 为我们提供了 json 和 form 的解析器
- 因为 json 和 form 很常用, 所有一般在 settings.py 中配置全局解析器
APIView 总结
- 之后 view 继承了 APIView 或者之上的, 才能定义
authentication_classes
, permission_classes
, parser_classes
, throttle_class
, 因为 APIView 重写了 dispatch, 在 dispatch 中有对应的 perform_authentication
, perform_permission
和 perform_throttle
- APIView 直接继承 View, 具体的业务逻辑要是要放在 get, post, put 等方法中
- 除了 Parser, 我们都要自定义 authentication, permission 等, 不使用内置的
GenericView
- 继承自 APIView, 相对于 APIView 多了
queryset
, ``
基于 Token
- 添加模块
INSTALLED_APPS = [
'rest_framework.authtoken'
]
- 执行
./manage.py makemigrations && ./manage.py migrate
- 在 urls.py 添加
from rest_framework.authtoken import views
urlpatterns = [
path('api-token-auth/', views.obtain_auth_token)
]
- 在 settings.py 中添加
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication'
)
}
- 请求头格式
Authorization: Token yourtoken
- 基于 Token 的缺点
- Token 是永久保存的, 对于用户来说不安全
- Token 难以在分布式中发挥作用
基于 JWT
- 安装 JWT,
pip install djangorestframework-jwt
- 在 settings.py 中配置
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
)
}
- 在 urls.py 中添加路由,
path('jwt-auth/', obtain_jwt_token)
, 可以根据业务修改'jwt-auth/' 为 'login/', 导入模块 from rest_framework_jwt.views import obtain_jwt_token
Django 请求基础
Django 中请求到达的流程
- 经过中间件, 每一个中间件可以实现如下五个方法
process_request
process_view
process_exception
process_response
process_template_response
- 中间件经过的流程
- 第一遍, 调用所有中间件的
process_request
, 最后到达路由系统, 获取到 view 函数 - 第二遍, 调用所有中间件的
process_view
方法, 达到最后的 view 函数体内 - 如果没有异常就反过来调用
process_response
或者 process_template_response
返回
- 中间件(全局)可以实现的功能, 这些功能在 view 逻辑中都可以实现, 但是会造成代码的冗余
- 登录认证
- 权限
- crsf
- FBV 让一个视图函数免除 crsf 校验, 需要在函数中上添加装饰器
@crsf_exempt
- CBV 则在类名上
@method_decrator(crfs_exempt, 'dispatch')