You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

元类如何访问子类定义的属性?基于DRF权限类封装的实现问题

解决方案

你可以通过给抽象基类加跳过校验标记的方式实现需求,只需要两步修改:

  1. 调整元类逻辑,新增抽象类跳过规则,同时修复原代码中类属性赋值不生效的问题(元类__init__执行时类已创建完成,直接修改attrs不会更新类属性,需操作当前类对象self):
from rest_framework.permissions import BasePermission


class ScopedPermissionMeta(type(BasePermission)):

    def __init__(self, name, bases, attrs):
        # 标记为__abstract__的类跳过required_scopes校验
        if attrs.get('__abstract__', False):
            return
        
        try:
            required_scopes = attrs['required_scopes']
        except KeyError:
            raise TypeError(f'{name} must include required_scopes attribute.')

        required_scopes_list = ' '.join(required_scopes)
        # 直接给类对象绑定属性
        self.message = f'Resource requires scope={required_scopes_list}'

        def has_permission(self, request, _view):
            """Check required scopes against requested scopes."""
            try:
                requested_scopes = request.auth.claims['scope']
            except (AttributeError, KeyError):
                return False

            return all(scope in requested_scopes for scope in required_scopes)

        # 直接给类对象绑定方法
        self.has_permission = has_permission
  1. 给中间基类添加__abstract__标记,元类会自动跳过对它的校验:
class ScopedPermission(BasePermission, metaclass=ScopedPermissionMeta):
    __abstract__ = True

修改完成后业务子类的写法完全符合你的预期:

class ReadJwtPermission(ScopedPermission):
    required_scopes = ['read:jwt']

该方案支持多层继承扩展,如果后续需要新增中间通用基类,只需要给对应类加上__abstract__ = True即可跳过校验,不会影响业务层的使用。

内容的提问来源于stack exchange,提问作者Brady Dean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 14:15:04