Django Rest Framework

Django Rest Framework

安装

  1. pip install djangorestframework
  2. pip install markdown
  3. pip install django-filter
  4. pip install coreapi
  5. 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',
]

跨域配置

  1. pip install django-cors-headers
  2. 在 settings.py 中添加
INSTALLED_APPS = [
'coreschema'
]
  1. 在 MIDDLEWARE 中添加
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware' # 放在第一行
]
  1. 在 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, 也很简单可以看懂
    • 主要关注
      1. self.request = self.initialize_request
      2. self.initialize
      3. self.perform_authentications
      4. self.perform_permissions

drf 定义认证类

  1. 继承 BaseAuthentication, 该类只是一个接口, 要求子类实现 authenticate(request) 和 authenticate_header 方法, 这种方式是最常用的, 因为可以自定义
  2. authenticate 方法一个 tuple, 第一个为 user, 第二个为 token, 返回之后会被 APIView 放在 request 中
  3. authenticate_header 一般不用重写
  4. 返回值
    1. None: None 表示继续下一个认证
    2. 抛出异常, 表示认证失败, drf 会直接返回自己定义的 response
    3. (user, token): user 为用户名, token 为 token 字符串
  5. 使用
    1. 在 class 中定义 authenticate_classes list, 放入认证类
    2. 在 settings.py 中, 定义 REST_FRAMEWORK 配置全局

权限控制

  • 和 drf 的认证类一样
  • 继承 BasePermission, 实现 has_permission 方法, 如果有权限则返回 True, 否则 返回 False

访问频率控制

  • 和 drf 的认证类一样
  • 继承 BaseThrottle, 实现 allow_requestwait 方法, 其中 allow_request 要求返回 True 或者 False, 而 wait 返回字符串, 在返回给用户时提示还要有多久才能继续访问

解析器

  • 在 django 和 drf 中解析器就是将 request 中的 body 接地刀 request 的 POST 中方便开发者获取, 我们一般不需要定义自己的解析器, drf 为我们提供了 json 和 form 的解析器
  • 因为 json 和 form 很常用, 所有一般在 settings.py 中配置全局解析器

APIView 总结

  1. 之后 view 继承了 APIView 或者之上的, 才能定义 authentication_classes, permission_classes, parser_classes, throttle_class, 因为 APIView 重写了 dispatch, 在 dispatch 中有对应的 perform_authentication, perform_permissionperform_throttle
  2. APIView 直接继承 View, 具体的业务逻辑要是要放在 get, post, put 等方法中
  3. 除了 Parser, 我们都要自定义 authentication, permission 等, 不使用内置的

GenericView

  1. 继承自 APIView, 相对于 APIView 多了 queryset, ``

基于 Token

  1. 添加模块
INSTALLED_APPS = [
'rest_framework.authtoken'
]
  1. 执行 ./manage.py makemigrations && ./manage.py migrate
  2. 在 urls.py 添加
from rest_framework.authtoken import views
urlpatterns = [
path('api-token-auth/', views.obtain_auth_token)
]
  1. 在 settings.py 中添加
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication'
)
}
  • 请求头格式

    1. Authorization: Token yourtoken
  • 基于 Token 的缺点

    1. Token 是永久保存的, 对于用户来说不安全
    2. Token 难以在分布式中发挥作用

基于 JWT

  1. 安装 JWT, pip install djangorestframework-jwt
  2. 在 settings.py 中配置
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
)
}
  1. 在 urls.py 中添加路由, path('jwt-auth/', obtain_jwt_token), 可以根据业务修改'jwt-auth/' 为 'login/', 导入模块 from rest_framework_jwt.views import obtain_jwt_token
  • 请求头格式

    1. Authorization: KWT yourtoken, 这里的 Token 要比基于 Token 要长很多
  • jwt 默认是使用用户名和密码认证的, 如果希望使用手机认真需要使用自定义认证后端

    1. 在 settings.py 中添加
    AUTHENTICATION_BACKEND = ['user.views.CustomBackend'] # 最后的名字是类名
    JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7), # 有效时间
    'JWT_AUTH_HEADER_PREFIX': 'JWT' # 前端的为 JWT, 后端保持一致也为 JWT
    }
    1. 如何制定 CustomBackend

      1. 在 user/views.py 中定义 CustomBackend 类, 继承 django.contrib.auth.backends import ModelBackend
      2. 重写 authenticate 方法, 参数为 username, password, *args,\ **kwargs
      3. 示例
      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 中请求到达的流程

  • 经过中间件, 每一个中间件可以实现如下五个方法

    1. process_request
    2. process_view
    3. process_exception
    4. process_response
    5. process_template_response
  • 中间件经过的流程

    1. 第一遍, 调用所有中间件的 process_request, 最后到达路由系统, 获取到 view 函数
    2. 第二遍, 调用所有中间件的 process_view 方法, 达到最后的 view 函数体内
    3. 如果没有异常就反过来调用 process_response 或者 process_template_response 返回
  • 中间件(全局)可以实现的功能, 这些功能在 view 逻辑中都可以实现, 但是会造成代码的冗余

    1. 登录认证
    2. 权限
    3. crsf
      • FBV 让一个视图函数免除 crsf 校验, 需要在函数中上添加装饰器@crsf_exempt
      • CBV 则在类名上 @method_decrator(crfs_exempt, 'dispatch')
posted @   gogogo11  阅读(214)  评论(0编辑  收藏  举报
编辑推荐:
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
阅读排行:
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· 软件产品开发中常见的10个问题及处理方法
· Vite CVE-2025-30208 安全漏洞
· MQ 如何保证数据一致性?
点击右上角即可分享
微信分享提示