drf-路由和认证
Posted liqianxin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了drf-路由和认证相关的知识,希望对你有一定的参考价值。
drf-路由
1 路由
针对视图集ViewSet,我们出来可以自己手动指明请求方式与执行函数间的对应关系,还可以使用Routers来快速实现路由信息
Rest-framework提供了两个router:SimpleRouter和DefaultRouter。前者较为简洁,后者产生路由相对较多。
1.1 路由router的使用
路由的配置有三种方式:
# 1 在urls中配置
url(r‘^books/(?P<pk>d+)‘, views.BookView.as_view(),
url(r‘^books/‘, views.BooksView.as_view(),
# 2 继承了ViewSetMixin,路由就需要指定对应关系
url(r‘^books/(?P<pk>d+)‘, views.BookView.as_view(actions={‘get‘:‘retrieve‘, ‘put‘:‘update‘,‘delete‘:‘destroy‘})),
url(r‘^books/‘, views.BooksView.as_view(actions={‘get‘:‘list‘, ‘post‘:‘create‘}))
# 3 继承视图类ModelViewSet,路由可以自动生成
urls.py
# 第一步:导入routers模块
from rest)framework import routers
# 第二步:有两个类,实例化得到对象
routers.DefaultRouter 生成的路由更多
routers.SimpleRouter 有两个路由
# 第三步:注册 router.register(‘前缀‘,‘视图集类‘,‘别名‘)
router.register(‘books‘,views.BookViewSet)
# 第四步:拼接到原路由中
urlpatterns += router.urls
1.2 action的使用
action可以给继承子ModelViewSet的视图类中定义的函数也添加路由
from rest_fromwork.decorates import action
class BookView(ModelViewSet):
queryset=Book.objects.all()
serializer_class = BookSerializer
@action(methods=[‘get‘], detail=True)
def get_1(self, request):
book = self.get_queryset()[:2]
ser = self.get_serializer(book, many=True)
return Response(ser.data)
methods中传入的时列表,列表中放的是请求方式。
detail:布尔类型,决定是否在路由中带pk值
True:xxx/<pk>/action方法名/
False:xxx/action方法名
当需要使用pk的时候就设置为True,否则就设置为False
2 认证
2.1 认证的写法
实现认证的步骤:
- 写一个类,继承BaseAuthentication,重写authenticate,认证的逻辑卸载里卖弄,认证通过,返回两个值,一个值给了request对象的user,一个给了request对象的auth。认证失败的话,就抛出异常
- 全部使用和局部使用
2.2 源码分析
认证、权限、频率的执行代码都是在APIView》dispatch方法》self.initial(request,*args,**kwargs) 中的try下。
‘‘‘
self.perform_authentication(request)为认证源码,内部就只有一句:request.user。需要去drf中Request对象中找user属性。
查找发现,user是一个方法。
‘‘‘
@property
def user(self):
if not hasattr(self, ‘_user‘): # 刚开始并没有_user
with wrap_attributeerrors():
self._authenticate() # 执行这个
return self._user
# 要点
def _authenticate(self):
# 遍历拿到self.authenticators认证器对象中一个个验证器进行验证
# authentication_classes=[认证类1,认证类2]
for authenticator in self.authenticators:
try:
# 认证方法authenticate(self,request)
# 返回值:登录的用户与认证的信息组成的tuple
user_auth_tuple = authenticator.authenticate(self) # 此时的self代表的是request对象
except exceptions.APIException:
self._not_authenticated()
raise
if user_auth_tuple is not None:
self._authenticator = authenticator
# 如何有返回值,就将 登陆用户 与 登陆认证 分别保存到 request.user、request.auth
self.user, self.auth = user_auth_tuple
return
# 如果返回值user_auth_tuple为空,代表认证通过,但是没有 登陆用户 与 登陆认证信息,代表游客
self._not_authenticated()
2.3 认证组件的使用
# 写一个认证类app_auth.py
from rest_framework.authemtication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from app01.models import UserToken
class Authentication_app(BaseAuthentication):
def authenticate(self, request):
token = request.GET.get(‘token‘)
if token:
user_token = UserToken.objects.fiter(token=token).first()
if user_token:
return user_token.user, token
else:
raise AuthenticationFailed(‘认证失败‘)
else:
raise AuthenticationFailed(‘不含有token‘)
# 全局使用和局部使用
# 全局使用
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.Authentication_app",]
}
# 局部使用,在视图类上写
authentication_classes=[MyAuthentication]
authentication_classes=[] # 表示禁用认证。
以上是关于drf-路由和认证的主要内容,如果未能解决你的问题,请参考以下文章
drf框架 6 视图集与路由组件(开发最常用最高级) 三大认证原理 RBAC认证规则
Express实战 - 应用案例- realworld-API - 路由设计 - mongoose - 数据验证 - 密码加密 - 登录接口 - 身份认证 - token - 增删改查API(代码片段