DRF第七天
昨日回顾
两个视图基类 还需要写get post 等方法
APIView
GenericAPIView
定义了queryset 和 serializer_class lookup_field 三个属性 第三个可以不写
定义了 get_queryset 和 get_object 和 get_serializer 三个方法
五个视图拓展类 from rest_framework. mixins import
UpdateModelMixin,
ListModelMixin,
DestroyModelMixin,
RetrieveModelMixin,
CreateModelMixin
但是如果实现多个接口需要多个继承 于是再次封装
九个视图子类 from rest_framework. generics import
ListAPIView,
CreateAPIView,
UpdateAPIView,
DestroyAPIView,
RetrieveAPIView,
ListCreateAPIView,
RetrieveDestroyAPIView,
RetrieveUpdateAPIView,
RetrieveUpdateDestroyAPIView,
视图集from rest_framework. viewsets import
ModelViewSet,
ReadOnlyModelViewSet,
ViewSet,
ViewSetMixin,
GenericViewSet,
- 自动生成路由(SimpleRouter,DefaultRouter)
router. register( 'book' ,'BookView' )
127.0 .0 .1 : 8080 / book
重写了as_view 路由可以有一个方法了,不需要俩方法 也返回了view的内存地址 view里面action就是路由层传过来的字典
path( 'publish/' , views. Publish. as_view( { 'get' : 'list' , 'post' : 'create' } ) ) ,
今日内容
登录接口
class User ( ModelViewSet) :
queryset = models. User. objects. all ( )
serializer_class = UserSerializer
@action ( methods= [ 'POST' ] , detail= False )
def login ( self, request) :
name = request. data. get( 'name' )
password = request. data. get( 'password' )
user_obj = models. User. objects. filter ( name= name, password= password) . first( )
if user_obj:
token = str ( uuid. uuid4( ) )
user_token = models. UserToken. objects. update_or_create( defaults= { 'token' : token} , user= user_obj)
print ( user_token)
return Response( { 'code' : 100 , 'msg' : '登录成功' , 'token' : token} )
else :
return Response( { 'code' : 101 , 'msg' : '用户名或者密码错误' } )
认证
- 第一步:写一个认证类,继承BaseAuthentication,重写authenticate 方法
- 第二步:在 authenticate 方法中判断用户是否登录(取出用户携带的token,去判断)
- 第三步:如果认证通过,返回两个值,如果认证不通过抛异常
-
- 第四步:把写的认证类,配置在视图类中(跟请求和响应的配置一样),全局配置
- 鸭子类型:不需要显示的继承某个类,只要类中有共同的属性和方法,我们就是同一类
非鸭子类型:比如 狗和猫 必须继承 动物类 他俩才是动物类
1.1认证的使用
from rest_framework. authentication import BaseAuthentication
from . models import UserToken
from rest_framework. exceptions import AuthenticationFailed
class LoginAuth ( BaseAuthentication) :
def authenticate ( self, request) :
token = request. META. get( 'HTTP_TOKEN' )
user_token = UserToken. objects. filter ( token= token) . first( )
print ( user_token)
if user_token:
return user_token. user, token
else :
raise AuthenticationFailed( '没有登录' )
1.2全局配置和局部配置 class BookView ( ModelViewSet) :
authentication_classes = [ LoginAuth]
queryset = models. Book2. objects. all ( )
serializer_class = BookSerializer
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES' : [
'app01.auth.LoginAuth'
] ,
}
权限
1 :写一个权限类,继承BasePermission,重写has_permission 方法
2 :在 重写has_permission 方法中判断用户是否有权限(request. user. user_type)认证后才可以知道有什么权限
3 :如果有权限,返回True ,如果返回False
4 :把写的权限类,配置在视图类中(跟请求和响应的配置一样),全局配置
2.1权限的使用
from rest_framework. permissions import BasePermission
class CommonUser ( BasePermission) :
def has_permission ( self, request, view) :
if request. user. user_type in [ 1 , 2 ] :
return True
else :
return False
class Administrator ( BasePermission) :
def has_permission ( self, request, view) :
if request. user. user_type in [ 2 ] :
return True
else :
return False
2.2权限的局部配置和全局配置 全局配置
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES' : [
'app01.auth.CommonUser' ,
'app01.auth.Administrator' ,
] ,
}
局部配置
permission_classes= [ 权限类名]
那么 登录接口权限设置应该为空 这个接口就是谁都可以访问 登陆之后才可以确认是什么权限
图书接口 所有人都可以访问 应该也设置为空
出版社 设置成自己的权限
频率
- 第一步:写一个类,继承SimpleRateThrottle,重写get_cache_key
- 第二步:get_cache_key返回什么就以什么做限制,必须写类属性 scope= '字符串' 限制了
- 第三步:配置文件中配置
'DEFAULT_THROTTLE_RATES' : {
'字符串' : '3/m' ,
} ,
- 第四步:局部使用和全局使用
3.1频率的使用
from rest_framework. throttling import BaseThrottle, SimpleRateThrottle
class MyThrottling ( SimpleRateThrottle) :
scope = 'ip_1_3'
def get_cache_key ( self, request, view) :
return request. META. get( 'REMOTE_ADDR' )
'DEFAULT_THROTTLE_RATES' : {
'ip_1_3' : '3/m' ,
} ,
3.2频率的全局配置和局部配置
'DEFAULT_THROTTLE_CLASSES' : [ 'app01.auth.MyThrottling' ] ,
throttle_classes = [ MyThrottling]
权限源码
self. perform_authentication( request)
self. check_permissions( request)
self. check_throttles( request)
def check_permissions ( self, request) :
for permission in self. get_permissions( ) :
if not permission. has_permission( request, self) :
self. permission_denied(
request,
message= getattr ( permission, 'message' , None ) ,
code= getattr ( permission, 'code' , None )
)
def get_permissions ( self) :
"""
Instantiates and returns the list of permissions that this view requires.
"""
return [ permission( ) for permission in self. permission_classes]