mapping={
'get': 'list', # 群查
'post': 'create', # 单增、群增
'put': 'multiple_update', # 群整改
'patch': 'multiple_partial_update', # 群局改
'delete': 'multiple_destroy', # 群删
},
mapping={
'get': 'retrieve', # 单查
'put': 'update', # 单整改
'patch': 'partial_update', # 单局改
'delete': 'destroy' # 单删
},
RetrieveAPIView (mixins.RetrieveModelMixin, GenericAPIView) 视图工具类,继承工具视图类的mixins.RetrieveModelMixin,实现单查
ListAPIView (mixins.ListModelMixin, GenericAPIView) 群查
RetrieveUpdateDestroyAPIView (mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, GenericAPIView) 单查、单整体改、单局部改、单删
ViewSetMixin类
GenericViewSet 继承自ViewSetMixin, GenericAPIView,
ReadOnlyModelViewSet,ModelViewSet两个视图集子类继承自GenericViewSet,就是做了一堆mixin与GenericViewSet相结合,自己在urls文件中配置as_view设置映射关系
authentication 认证
permission 权限
throttle 频率
# -------------------- 三大认证 --------------------
"""
# 认证
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication'
],
# 权限
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
],
# 频率
throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
'DEFAULT_THROTTLE_CLASSES': [],
"""
# 认证组件
# 配置自定义认证类(需求小)
# authentication_classes = [authentications.MyAuthentication]
# 配置drf-jwt框架的认证类(需求大) => 配置还可以在全局(认证组件只能决定request.user,不是断定权限的地方,所以一般配置全局)
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
# authentication_classes = [JSONWebTokenAuthentication]
# 权限组件
# 配置自定义权限类(有需求)
# permission_classes = [permissions.MyPermission]
# 配置drf自带的权限类(有需求)
from rest_framework.permissions import IsAuthenticated, IsAdminUser, AllowAny, IsAuthenticatedOrReadOnly
# permission_classes = [IsAuthenticated]
# permission_classes = [IsAdminUser]
# 频率组件
# 配置drf自带的频率类(有需求)
from rest_framework.throttling import AnonRateThrottle, UserRateThrottle
# throttle_classes = [UserRateThrottle]
# throttle_classes = [AnonRateThrottle]
# 配置自定义的频率类(需求大)
from rest_framework.permissions import BasePermission
class MyPermission(BasePermission):
def has_permission(self, request, view):
print(request.user, request.auth) #auth就是token,由HTTP_AUTHORIZATION带过来
return False
#VIP用户权限
class VIPUserPermission(BasePermission):
def has_permission(self, request, view):
for group in request.user.groups.all():
if group.name.lower()=='vip':
return True
return False
#settings.py
# drf框架自定义配置
REST_FRAMEWORK = {
# 异常模块:异常处理函数
'EXCEPTION_HANDLER': 'api.exception.exception_handler',
# 认证组件
'DEFAULT_AUTHENTICATION_CLASSES': [
# 'rest_framework.authentication.SessionAuthentication',
# 'rest_framework.authentication.BasicAuthentication'
'rest_framework_jwt.authentication.JSONWebTokenAuthentication'
],
# 频率组件:频率类一般做局部配置,但是频率调节在settings中配置
'DEFAULT_THROTTLE_RATES': {
'user': '5/min',
'anon': '3/min',
'mobile': '1/min'
},
}
# drf-jwt自定义配置
import datetime
JWT_AUTH = {
# 过期时间
'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300),
# 是否允许刷新
'JWT_ALLOW_REFRESH': False,
# 最大刷新的过期时间
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
}
from rest_framework.throttling import SimpleRateThrottle
class MobileRateThrottle(SimpleRateThrottle):
scope='mobile'
def get_cache_key(self, request, view):
if not request.user.is_authenticated or not request.user.mobile:
return None #匿名用户 或没有电话号的用户 都不限制
#有电话号的用户都限制
return self.cache_format %{
#%s无名占位
#%(scope)s有名占位,后面跟字典 eg:%(scope)s % {'scope':123}
'scope':self.scope, #
'ident':request.user.mobile #不同匿名用户的唯一标识
}
def validate(self, attrs):
credentials = {
self.username_field: attrs.get(self.username_field),
'password': attrs.get('password')
}
if all(credentials.values()):
user = authenticate(**credentials)
if user:
if not user.is_active:
msg = _('User account is disabled.')
raise serializers.ValidationError(msg)
payload = jwt_payload_handler(user)
return {
'token': jwt_encode_handler(payload),
'user': user
}
else:
msg = _('Unable to log in with provided credentials.')
raise serializers.ValidationError(msg)
else:
msg = _('Must include "{username_field}" and "password".')
msg = msg.format(username_field=self.username_field)
raise serializers.ValidationError(msg)
from rest_framework.views import APIView
class LoginAPIView(APIView):
authentication_classes = []
pagination_class = []
def post(self, request, *args, **kwargs):
serializer = serializers.LoginModelSerializer(data=request.data)
serializer.is_valid(raise_exception=True) # 内部在全局钩子中完成token的签发
return APIResponse(results={
'username': serializer.content.get('user').username,
'token': serializer.content.get('token')
})
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
import re
class LoginModelSerializer(serializers.ModelSerializer):
# post请求,序列化默认当做create动作进行校验,需要校验数据库,create动作username会抛用户已存在异常
# 抛用户已存在异常是多余的,所以自定义系统校验规则即可
username = serializers.CharField(min_length=3, max_length=16)
password = serializers.CharField(min_length=3, max_length=16)
class Meta:
model = models.User
fields = ('username', 'password')
# 用全局钩子,完成token的签发
def validate(self, attrs):
# 1)通过 username 和 password 完成多方式登录校验,得到user对象
user = self._validate_user(attrs)
# 2)user对象包装payload载荷
payload = jwt_payload_handler(user)
# 3)payload载荷签发token
token = jwt_encode_handler(payload)
# 4)将user与token存储到serializer对象中,方便在视图类中使用
self.content = {
'user': user,
'token': token
}
return attrs
def _validate_user(self, attrs):
username = attrs.get('username')
password = attrs.get('password')
if re.match(r'.*@.*', username): # 邮箱
user = models.User.objects.filter(email=username).first() # type: models.User
elif re.match(r'^1[3-9][0-9]{9}$', username): # 电话
user = models.User.objects.filter(mobile=username).first()
else: # 用户名
user = models.User.objects.filter(username=username).first()
if not user or not user.check_password(password):
raise serializers.ValidationError({'message': '用户信息异常'})
return user
游客也存在request.user中,是匿名用户
原文:https://www.cnblogs.com/lidandanaa/p/12142260.html