Django rest framework框架
一、十个方面
权限 认证 访问频率限制 序列化 路由 视图 分页 解释器 渲染器 版本
二、Django REST framework框架介绍
用于构建Web API,官方网站:https://www.django-rest-framework.org/
三、安装
pip install djangorestframework
pip install markdown #支持可浏览的API
pip install django-filter # 过滤支持
四、设置setting.py文件
#将项目添加到APP中
INSTALLED_APPS = [ ... 'rest_framework', ]
#添加中间件
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
]
}
五、用户登录API+验证
1.创建用户表和用户登录验证的token
#models.py文件 class UserInfo(models.Model): user_type_choices=( (1,'普通用户'), (2, 'VIP'), (3, 'SVIP'), ) id = models.AutoField(primary_key=True) user_type = models.IntegerField(choices=user_type_choices,verbose_name='用户等级') username = models.CharField(max_length=32,unique=True,verbose_name='用户名') password = models.CharField(max_length=64,verbose_name='用户密码') class UserToken(models.Model): user = models.OneToOneField(to='UserInfo') token = models.CharField(max_length=64,verbose_name='用户的token')
2.创建用户Token的md5算法
#当前算法使用的hashlib的md5算法加上时间 import hashlib import time def md5(user): ctime = str(time.time()) m = hashlib.md5(bytes(user,encoding='utf-8')) m.update(bytes(ctime,encoding='utf-8')) return m.hexdigets()
3.根据用户名创建Token
from rest_framework.views import APIView class AuthView(APIView): def post(self, request, *args, **kwargs): ret = {'code': 1000, 'msg': None} try: # 获取用户名 user = request._request.POST.get('username') # 获取密码 pwd = request._request.POST.get('password') # 核对数据的正确性 obj = models.UserInfo.object.filter(username=user, password=pwd).first() if not obj: ret['code'] = 1001 ret['msg'] = '用户名或密码错误' # 为登录用户创造token token = md5(user) # 存在就更新,不存在就创新 models.UserToken.object.update_or_create(user=obj, defaults={'token': token}) ret['token'] = token except Exception as e: ret['code'] = 1002 ret['msg'] = '请求异常' return JsonResponse(ret)
4.验证用户传递的Token是否正确,来验证登录用户是否正确
class Authtication(BasicAuthentication): def authenticate(self, request): token = request._request.Get.get('token') token_obj = models.UserToken.object.filter(token=token).first() if not token_obj: raise exceptions.AuthenticationFailed('用户验证失败') return (token_obj.user,token_obj) def authenticate_header(self, request): pass
5.修改settings.py配置文件,加装全局变量配置
REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES":['函数所在路径.函数名,如:api.utils.auth.Authtication'] }
6.在其他视图函数中引用配置文件,完成只有登录用户才可以访问的控制
authentication_classess= []
六、匿名用户登录
1.修改settings.py配置文件,加装全局变量配置
REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ['函数所在路径.函数名,如:api.utils.auth.Authtication'], "UNAUTHENTICATED_USER": None, "UNAUTHENTICATED_TOKEN": None }
2.创建匿名用户的验证函数
class FirstAuthtication(BasicAuthentication): def authenticate(self, request): pass def authenticate_header(self, request): pass
七、按权限限定用户访问的页面
1.创建限制用户权限的函数
from rest_framework.permissions import BasePermission class MyPermission(BasePermission):
message = "只用3级用户才可以访问" def has_permission(self, request, view): #只有3级用户才可以访问 if request.user.user_type !=3: return False else: return True
2.视图函数使用验证方法(推举使用该方法,而不是全局配置)
permission_classess = [MyPermission,]
八、控制访问频率次数
1.创建访问频率次数的方法函数
import time from rest_framework.throttling import BaseThrottle VISIT_RECORD={} class VisitThrottle(BaseThrottle): #60秒只能访问3次 def __init__(self): self.history = None def allow_request(self, request, view): #获取用户的IP,根据IP进行控制 ip = request.META.get("REMOTE_ADDR") ctime = time.time() if ip not in VISIT_RECORD: VISIT_RECORD[ip]=[ctime,] return True history = VISIT_RECORD.get(ip) self.history = history while history and history[-1] < ctime - 60: history.pop() if len(history) < 3: history.insert(0,ctime) return True def wait(self): ''' 需要等待多长时间再次访问 :return: ''' ctime = time.time() return 60 -(ctime-self.history[-1])
2.使用框架内部的控制策略
#修改配置文件信息,settings.py REST_FRAMEWORK = { "DEFAULT_THROTTLE_RATES":{ "IP":'3/m', "UserName":'10/m' } } #设置控制策略函数 from rest_framework.throttling import SimpleRateThrottle class VisitThrottle(SimpleRateThrottle): #根据IP的访问控制 scope = "IP" def get_cache_key(self, request, view): return self.get_ident(request) class UserThrottle(SimpleRateThrottle): #根据用户名的访问控制 scope = "UserName" def get_cache_key(self, request, view): return request.user.username
九、版本控制策略
#修改配置文件信息 REST_FRAMEWORK = { #默认版本号 "DEFAULT_VERSION":'v1', #允许的版本号 "ALLOWED_VERSIONS":['v1','v2'], #版本的Key的值 "VERSION_PARAM":'version' } #引用版本规则 from rest_framework.versioning import QueryParameterVersioning class UserView(): versioning_class = QueryParameterVersioning def get(self,request,*args,**kwargs): print(request.version) return
十、解释器
from rest_framework.parsers import JSONParser,FormParser #JSON解释器,POST解释器, parser_classes = [JSONParser,FormParser]
请求头:
- User-Agent:产生请求的浏览器类型。
- Accept:客户端可识别的内容类型列表。
- Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机。
状态码:
- 1xx:指示信息--表示请求已接收,继续处理。
- 2xx:成功--表示请求已被成功接收、理解、接受。
- 3xx:重定向--要完成请求必须进行更进一步的操作。
- 4xx:客户端错误--请求有语法错误或请求无法实现。
- 5xx:服务器端错误--服务器未能实现合法的请求。
请求方法:
十一、序列化
1.基础用法
#序列化方法函数 from rest_framework import serializers class UserINfoSerializer(serializers.Serializer): #带choise的序列化 x1 = serializers.CharField(source="user_type") #直接获得choise的中文内容 x2 = serializers.CharField(source="get_user_type_display") #正常的序列化 username = serializers.CharField() #一对多 gp = serializers.CharField(source="group.title") #多对多 rls = serializers.SerializerMethodField()#自定义显示 def get_rls(self,row): role_obj_list = row.roles.all() ret = [] for item in role_obj_list: ret.append({"id":item.id,"title":item.title}) return ret #引入序列化 class UserInfoView(APIview): def get(self,request,*args,**kwargs): user = models.UserInfo.object.all() ser = UserINfoSerializer(instance=user,many=True) ret = json.dumps(ser.data,ensure_ascii=False) return HttpResponse(ret)
2.使用自带的序列化方法
#序列化方法函数 from rest_framework import serializers class UserINfoSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo #获取所有的内容 #fields = "__all__" #自定义获取的内容 fields = ['id','username'] depth = 0 #获取到的层级 0-10 #使用序列化方法 class UserInfoView(APIView): def get(self,request,*args,**kwargs): users = models.UserInfo.objcet.all() ser = UserINfoSerializer(instance=users,many=True,context={'request':request}) ret = json.dumps(ser.data,ensure_ascii=False) return HttpResponse(ret)
3.序列化验证
#验证方法 from rest_framework import serializers class XXValidator(object): def __init__(self,base): self.base = base def __call__(self,value): if not value.startswith(self.base): message = 'XXX的%s错误' % self.base raise serializers.ValidationError(message) #引入验证方法 class UserGroupSerializer(serializers.Serializer): title = serializers.CharField(error_messages={'required':'XXX问题'},validators=[XXValidator('内容'),])
十二、分页
from rest_framework.views import APIView from rest_framework.pagination import PageNumberPagination #自定义显示内容 class MypageNumberPagination(PageNumberPagination): page_size = 2 #每页显示的内容 page_query_param = 'page'#key值 #只用自定义显示的内容 class PagerView(APIView): def get(self,request,*args,**kwargs): #获取所有数据 roles = models.Role.object.all() #创建分页对象 pg = PageNumberPagination() #获取分页数据 pager_roles = pg.MypageNumberPagination(queryset=roles,request=request,view=self) #对数据进行序列化,PagerSerialiser的方法,需要自定义 ser = PagerSerialiser(instance=pager_roles,many=True) #返回基础数据 #return Response(ser.data) #返回带上一页,下一页地址的数据 return pg.get_paginated_response(ser.data)