Django Rest Framework
Django Rest Framework
安装
pip install djangorestframework
pip install markdown
pip install django-filter
pip install coreapi
pip install guardian
配置
- urls.py
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
-
请求头格式
Authorization: KWT yourtoken
, 这里的 Token 要比基于 Token 要长很多
-
jwt 默认是使用用户名和密码认证的, 如果希望使用手机认真需要使用自定义认证后端
- 在 settings.py 中添加
AUTHENTICATION_BACKEND = ['user.views.CustomBackend'] # 最后的名字是类名 JWT_AUTH = { 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7), # 有效时间 'JWT_AUTH_HEADER_PREFIX': 'JWT' # 前端的为 JWT, 后端保持一致也为 JWT } -
如何制定 CustomBackend
- 在 user/views.py 中定义 CustomBackend 类, 继承 django.contrib.auth.backends import ModelBackend
- 重写 authenticate 方法, 参数为 username, password, *args,\ **kwargs
- 示例
user = get_user_model() class CustomBackend(ModelBackend): def authenticate(self, username=None, password=None, *args, **kwargs):
⁃ try:
user = User.objects.get(Q(username=username) | Q(password=password))
print(user)
if user.check_password(password):
return user
except Exception as e:
return None
```
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')
- FBV 让一个视图函数免除 crsf 校验, 需要在函数中上添加装饰器
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· 软件产品开发中常见的10个问题及处理方法
· Vite CVE-2025-30208 安全漏洞
· MQ 如何保证数据一致性?