先说两个中间件,一个是在请求头中获取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',
}
}