rest_framework学习之“权限”

本文详细探讨了rest_framework中APIView的权限验证流程,从dispatch()到check_permissions(),讲解了如何通过has_permission方法判断权限。同时介绍了如何自定义权限类,包括必须实现的has_permission和has_object_permission方法。此外,还提到了全局权限验证的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天我们来看看rest_framework的APIView的权限验证过程是怎么走的。
一、 与认证的入口相似,权限验证也是从APIView的dispatch()到initial()方法,再到check_permissions(),通过返回True或者False来判断请求是否通过了权限验证:
def initial(self, request, *args, **kwargs):
	self.format_kwarg = self.get_format_suffix(**kwargs)
	neg = self.perform_content_negotiation(request)
	request.accepted_renderer, request.accepted_media_type = neg
	version, scheme = self.determine_version(request, *args, **kwargs)
	request.version, request.versioning_scheme = version, scheme
	# 认证
	self.perform_authentication(request)
	# 权限
	self.check_permissions(request)
	# 节流
	self.check_throttles(request)
二、 在check_permissions方法中,遍历了视图的get_permissions方法的返回值(返回的是列表形式存储的权限验证类的实例),并运行它们的has_permission方法。
def check_permissions(self, request):
	for permission in self.get_permissions():  # get_permissions方法返回了权限类的列表推导式
		if not permission.has_permission(request, self):  # 遍历权限类并执行has_permission方法
			self.permission_denied(
				request, message=getattr(permission, 'message', None)
	)
  • get_permissions从定义的视图中拿到permission_classes(列表格式,可包含多个权限类),并使用列表推导式将实例化的对象存放在列表并返回给check_permissions使用。
def get_permissions(self):
	return [permission() for permission in self.permission_classes]
三、 如果权限类的has_permission返回True,那么本次循环不做任何操作,继续执行下一个权限类的has_permission方法。如果全部返回True,那么本次权限验证全部通过,否则执行视图的permission_denied方法,
def permission_denied(self, request, message=None):
	if request.authenticators and not request.successful_authenticator:
		raise exceptions.NotAuthenticated()
	raise exceptions.PermissionDenied(detail=message)  # 抛出权限拒绝的错误

可以在视图类中添加message属性来定制权限验证失败后返回的信息。

四、 由APIView源码可以知道,权限类可以在视图类的permission_classes中设定,以列表的格式。
from rest_framework.permissions import AllowAny
from rest_framework.authentication import BaseAuthentication

class MyView(APIView):
	authentication_classes = [BaseAuthentication,]  # 认证类
	permission_classes = [AllowAny,]  # 权限类
	def get(self, request, *args, **kwargs):
		…………

rest_framework中内置了8中认证类:BasePermission、AllowAny、IsAuthenticated、IsAdminUser、IsAuthenticatedOrReadOnly、DjangoModelPermissions、DjangoModelPermissionsOrAnonReadOnly、DjangoObjectPermissions。

五、 与认证类同理,权限类如果设置在项目的配置文件中,就有了全局权限验证的效果:
REST_FRAMEWORK = {
	"DEFAULT_AUTHENTICATION_CLASSES": ["rest_framework.authentication.BaseAuthentication",],  # 认证类
	"DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.AllowAny"]  # 权限类
}
六、 如果想要自定义权限类,必须包含两个方法:has_permission(self, request, view)、has_object_permission(self, request, view, obj)。注意:方法中传递的参数也是不可省略的。
class Mypermissions(object):
	def has_permission(self, request, view):
		# VIP用户方可访问
		if request.user.group == 'VIP':
			return True
		return False
		
	def has_object_permission(self, request, view, obj):
		return True
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值