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')

转载于:https://www.cnblogs.com/megachen/p/11074719.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值