Django3 Rest framework自动生成接口文档、限流的使用

先说两个中间件,一个是在请求头中获取token,另一个是解决跨域问题

  • 文件目录结构如下
    在这里插入图片描述
  • CorsMiddleware.py 解决跨域问题
from django.utils.deprecation import MiddlewareMixin


# 跨域处理中间件
class Cors(MiddlewareMixin):
    def process_response(self, request, response):
        response["Access-Control-Allow-Origin"] = "*"
        if request.method == 'OPTIONS':
            response["Access-Control-Allow-Headers"] = 'Content-Type'
            response["Access-Control-Allow-Methods"] = 'GET,POST,PUT,PATCH,DELETE'
        return response

  • middleWare.py Token和响应的一些处理
import json
import time

from django.http import JsonResponse
from django.utils.deprecation import MiddlewareMixin
from django_redis import get_redis_connection

conn = get_redis_connection('default')


class MyMiddle(MiddlewareMixin):
    """
    自定义中间件:用来验证token
    """

    def process_request(self, request):
        request.start_time = time.time()
        token = request.META.get('HTTP_AUTHORIZATION', '')
        if "login" not in request.path and "admin" not in request.path and "media" not in request.path \
                and "favicon.ico" not in request.path and 'docs' not in request.path:  # 路径中如果没有"login"
            token = request.META.get('HTTP_AUTHORIZATION', '')
            token = token.split(" ")[-1]
            if token:
                try:
                    user = json.loads(conn.get(token))
                    if user:
                        request.META["user"] = user
                except:
                    return JsonResponse({"code": 400, "msg": "token失效"})
            else:
                return JsonResponse({"code": 400, "msg": "token失效"})

    def process_response(self, request, response):
        execute_time = time.time() - request.start_time
        path = request.get_full_path()
        print('路径:%s,响应时间为:%s' % (path, execute_time))
        return response

构建一个view 处理基础类

  • ComAPI.py
class MyAddAPI(APIView):
    """创建"""
    model = None
    uniq = None
    keys = []
    checked = False  # 是否需要字段校验
    others_key = []  # 外键需要重定义
    my_id = None
    schema = None
    """接口限流设置: 如果不需要则设置为: []"""
    throttle_classes = [throttle.VisitThrottle, throttle.UserThrottle]

    def post(self, request):
        params = get_parameter_dic(request)
        if self.checked:
            check, re_str = self.keys_check(request)
            if check:
                return JsonResponse({'code': 403, 'msg': re_str})
        if self.uniq:
            if self.model.objects.filter(**{self.uniq: params.get(self.uniq, '')}):
                return JsonResponse({'code': 402, 'msg': '唯一值已存在!'})
        user = request.META.get('user')
        _keys = {i: params.get(i, '') for i in self.keys}

        user_name = user['name']
        if hasattr(self.model, 'create_user'):
            _keys.update({'create_user': user_name})
        if hasattr(self.model, 'create_id'):
            _keys.update({'create_id': user['id']})
        _keys = {k: v for k, v in _keys.items() if v not in ['', [], None]}
        if self.keys_add(request):
            _keys.update(self.keys_add(request))
        with transaction.atomic():
            self.model.objects.create(**_keys)

        return JsonResponse({'code': 200, 'msg': '添加成功!'})

    @staticmethod
    def keys_check(req):
        # 用于检测字段类型的正确性
        return False, 'xxx格式错误!'

    @staticmethod
    def keys_add(req):
        # 用于自定义添加一些字段
        return {}

视图处理函数的处理

  • views.py
from src.CommonTools.ComAPI import *
from rest_framework.views import APIView

# 普通的接口
def create_schema(model, no_need_files, other_keys=[]):
    """
    创建schema
    :param model:
    :param no_need_files:
    :param other_keys:
    :return:
    """
    files_list = []
    for i in model._meta.fields:
        if i.name in other_keys:
            i.name = i.name + '_id'
        if i.name not in no_need_files:
            if not i.blank:
                files_list.append(coreapi.Field(name="{}".format(i.name), required=True, location="query",
                                                schema=coreschema.String(
                                                    description="{}, 默认值: ' {}'".format(i.verbose_name, i.default))))
            else:
                files_list.append(coreapi.Field(name="{}".format(i.name), location="query",
                                                schema=coreschema.String(
                                                    description="{}, 默认值: ' {}'".format(i.verbose_name, i.default))))
    schema = AutoSchema(manual_fields=files_list)
    return schema



class LoginAPI(APIView):
    model = None
    throttle_classes = [throttle.VisitThrottle, throttle.UserThrottle]
    schema = AutoSchema(manual_fields=[
        coreapi.Field(name="username", required=True, location="query", schema=coreschema.String(description="账号")),
        coreapi.Field(name="password", required=True, location="query", schema=coreschema.String(description="密码")),
    ])

    def post(self, request):
        params = get_parameter_dic(request)
        username = params.get('username', [])
        password = params.get('password', [])
        print(username,password)
        return JsonResponse({'code': 200, 'msg': '登录成功!','result':{'token':'xx12',}})

# 使用基础MyAddAPI中的方法
class LoginAPI2(MyAddAPI):
    model = Hospitals
    throttle_classes = [throttle.VisitThrottle, throttle.UserThrottle] # 如果此接口不需要限流则设置 throttle_classes = []
    no_need_files = ["id"]  # 不需要返回的字段
    others_key = ["patient"]  # 表中外键patient
    schema = create_schema(model, no_need_files=[], other_keys=[])

    def post(self, request):
        params = get_parameter_dic(request)
        username = params.get('username', [])
        password = params.get('password', [])
        print(username,password)
        return JsonResponse({'code': 200, 'msg': '登录成功!','result':{'token':'xx12',}})

请求头中添加token的处理

在这里插入图片描述

限流和跨域中间件的配置, 在settings 中添加以下代码

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'middleWare.CorsMiddleware.Cors',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'middleWare.middleWare.MyMiddle',
]

REST_FRAMEWORK = {
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',

    # 限流配置
    "DEFAULT_THROTTLE_CLASSES": ["utils.throttle.UserThrottle"],
    "DEFAULT_THROTTLE_RATES": {
        "anonymous": '50/m',
        "user": '100/m',
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值