视图集回顾
- GenericAPIView+ 5 个视图扩展类的组合- ListAPIView, CreateAPIView, DestroyAPIView, RetrieveAPIView, UpdateAPIView- ListCreateAPIView- RetrieveDestroyAPIView, RetrieveUpdateAPIView, RetrieveUpdateDestroyAPIView- class TestView ( ListAPIView) : querysetserializer_calss- ModelViewSet:GenericViewSet+ 5 个视图扩展类- 路由写法变了的5 个接口- PublishView. as_view( { 'get' : 'list' , 'post' : 'create' } ) - 自动生成路由:本质:把get和list 对应,把post和create对应- 可以重写父类方法,完成自己的定制- ReadOnlyModelViewSet:2 个接口,只读的- ViewSet:ViewSetMixin+ APIView- GenericViewSet:ViewSetMixin+ GenericAPIView- ViewSetMixin:重写了as_view 路由写法变了
ViewSetMixin+ ListAPIView- - - 》自动生成路由- 自动生成路由步骤- action装饰器- - - 》/ publish/ 被装饰函数名字/ post请求就会执行- @action( methods= [ 'POST' ] , detail= False )
class TestView ( GenericViewSet) : def list ( self, request) : return Response( 'sdafs' )
1 认证组件
1.1 登录功能
from rest_framework. views import APIView
from rest_framework. generics import GenericAPIView
from rest_framework. viewsets import ViewSetMixin, ViewSet
from rest_framework. response import Response
from rest_framework. decorators import action
from . models import User, UserToken
import uuid
class UserView ( ViewSet) : @action ( methods= [ 'POST' ] , detail= False ) def login ( self, request, * args, ** kwargs) : username = request. data. get( 'username' ) password = request. data. get( 'password' ) user = User. objects. filter ( username= username, password= password) . first( ) if user: token = str ( uuid. uuid4( ) ) UserToken. objects. update_or_create( defaults= { 'token' : token} , user= user) return Response( { 'code' : 100 , 'msg' : '登录成功' , 'token' : token, 'username' : user. username} ) else : return Response( { 'code' : 101 , 'msg' : '用户名或密码错误' } )
from rest_framework. routers import SimpleRouterrouter = SimpleRouter( )
router. register( 'user' , UserView, 'user' ) urlpatterns = [ path( 'admin/' , admin. site. urls) , path( '' , include( router. urls) ) ,
]
1.2 认证组件
- 一些接口,想限制登录后才能访问,没登录不能访问- 做登录认证,限制如果没登录,不允许访问该接口class BookView ( ViewSet) : authentication_classes = [ LoginAuth] request. user
1.2.1 auth.py
from . models import UserToken
from rest_framework. authentication import BaseAuthentication
from rest_framework. exceptions import AuthenticationFailedclass LoginAuth ( BaseAuthentication) : def authenticate ( self, request) : token = request. query_params. get( 'token' ) user_token = UserToken. objects. filter ( token= token) . first( ) if user_token: return user_token. user, token else : raise AuthenticationFailed( '您没有登录' )
1.2.2 视图类
from django. shortcuts import render
from rest_framework. views import APIView
from rest_framework. generics import GenericAPIView
from rest_framework. viewsets import ViewSetMixin, ViewSet
from rest_framework. response import Response
from rest_framework. decorators import action
from . models import User, UserToken
import uuidfrom . auth import LoginAuth
class UserView ( ViewSet) : @action ( methods= [ 'POST' ] , detail= False ) def login ( self, request, * args, ** kwargs) : username = request. data. get( 'username' ) password = request. data. get( 'password' ) user = User. objects. filter ( username= username, password= password) . first( ) if user: token = str ( uuid. uuid4( ) ) UserToken. objects. update_or_create( defaults= { 'token' : token} , user= user) return Response( { 'code' : 100 , 'msg' : '登录成功' , 'token' : token, 'username' : user. username} ) else : return Response( { 'code' : 101 , 'msg' : '用户名或密码错误' } ) class BookView ( ViewSet) : authentication_classes = [ LoginAuth] def list ( self, request) : print ( request. user. username) return Response( "你好:%s,你看到了好多书啊" % request. user. username)
1.2.3 路由
from rest_framework. routers import SimpleRouterrouter = SimpleRouter( )
router. register( 'user' , UserView, 'user' )
router. register( 'books' , BookView, 'books' )
urlpatterns = [ path( '' , include( router. urls) ) ,
]
1.3 小结
- 配置在视图类上- - - 》局部使用- 配置文件中配置- - 》全局使用- - - 》所有接口都必须登录后才能用REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES' : [ 'app01.auth.LoginAuth' ] , } - 局部禁用:class UserView ( ViewSet) : authentication_classes = [ ]
- 后端定的,我们这个项目是从请求地址中取- 还可以从请求头或请求体中取
2 权限组件
- 由于它的执行是在认证之后,所有从request. user中取出当前等用户,判断权限
class PublishView ( ViewSet) : permission_classes = [ UserPermission] REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES' : [ 'app01.auth.LoginAuth' ] , 'DEFAULT_PERMISSION_CLASSES' : [ 'app01.permissions.UserPermission' , ] ,
}
from rest_framework. permissions import BasePermission
class UserPermission ( BasePermission) : def has_permission ( self, request, view) : if request. user. user_type == 3 : return True else : self. message = '您的用户类型是:%s,您没有权限操作' % ( request. user. get_user_type_display( ) ) return False
2.1 django项目国际化
INSTALLED_APPS = [ 'rest_framework'
] LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
3 频率组件
''''DEFAULT_THROTTLE_RATES': {'drf_day08': '3/m', # 一分钟访问三次 5/s,m,h,d},''' class PublishView ( ViewSet) : throttle_classes = [ IPRateThrottle] 'DEFAULT_THROTTLE_CLASSES' : [ 'app01.throttling.IPRateThrottle' ] ,
from rest_framework. throttling import SimpleRateThrottle
''''DEFAULT_THROTTLE_RATES': {'drf_day08': '3/m', # 一分钟访问三次},
''' class IPRateThrottle ( SimpleRateThrottle) : scope = 'drf_day08' def get_cache_key ( self, request, view) : print ( request. META) return request. META. get( 'REMOTE_ADDR' )
4 排序
- 1 必须写在继承:GenericAPIView 类的视图类中才行- 2 配置类属性:filter_backends = [ OrderingFilter] ordering_fields= [ 'id' , 'user_type' ] - 3 使用:规定必须使用ordering 降序带负号http: // 127.0 .0 .1 : 8000 / user/ ?ordering= user_type http: // 127.0 .0 .1 : 8000 / user/ ?ordering= - user_type http: // 127.0 .0 .1 : 8000 / user/ ?ordering= user_type, - id
代码展示
from rest_framework. viewsets import GenericViewSet
from rest_framework. generics import ListAPIView
from rest_framework. mixins import ListModelMixin
from rest_framework. filters import OrderingFilterfrom . models import User
from . serializer import UserSerializer
class UserView ( GenericViewSet, ListModelMixin) : authentication_classes = [ ] permission_classes = [ ] throttle_classes = [ ] queryset = User. objects. all ( ) serializer_class = UserSerializerfilter_backends = [ OrderingFilter] ordering_fields = [ 'id' , 'user_type' ] @action ( methods= [ 'POST' ] , detail= False ) def login ( self, request, * args, ** kwargs) : username = request. data. get( 'username' ) password = request. data. get( 'password' ) user = User. objects. filter ( username= username, password= password) . first( ) if user: token = str ( uuid. uuid4( ) ) UserToken. objects. update_or_create( defaults= { 'token' : token, 'user' : user} ) return Response( { 'code' : 100 , 'msg' : '登录成功' , 'token' : token} ) return Response( { 'code' : 101 , 'msg' : '用户名或密码错误' } )