Django同目录自定义权限类导入settings.py失败问题求助
问题分析与解决方案
一、同目录权限类的配置错误
你在settings.py里用.permissions.My_has_permission这种相对路径是无效的,DRF的DEFAULT_PERMISSION_CLASSES要求完整的Python绝对导入路径——从已注册的应用包名开始,而非相对路径。
假设你的核心应用包名为core(即settings.py和permissions.py所在目录的包名,该目录需包含__init__.py),正确配置应为:
REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'core.permissions.My_has_permission', ] }
为什么相对路径不行?
DRF内部通过importlib导入类,相对导入需要显式指定package参数,但DRF的导入逻辑默认按绝对路径处理,直接用.开头的相对路径会触发TypeError。
二、permissions.py代码的致命问题
你的My_has_permission类存在语法与逻辑错误,根本无法运行:
- 类级别不能直接引用
view变量,view是权限方法的参数,只能在方法内部使用; - 类中直接写
return语句非法,DRF权限类必须实现has_permission或has_object_permission方法。
修正后的正确代码:
from rest_framework import permissions PERMS_MAP = { 'HEAD': 'view_', 'GET': 'view_', 'DELETE': 'delete_', 'PATCH': 'change_', 'POST': 'add_', 'PUT': 'change_' } class My_has_permission(permissions.BasePermission): def has_permission(self, request, view): # 先判断视图是否包含queryset,避免无queryset时报错 if not hasattr(view, 'queryset'): return False app_label = view.queryset.model._meta.app_label model_name = view.queryset.model._meta.model_name perm_code = f"{app_label}.{PERMS_MAP[request.method]}{model_name}" return ( request.user.has_perm(perm_code) or request.user.is_staff # Django默认管理员字段是is_staff,而非is_admin or request.user.is_superuser )
关键修正点:
- 将权限逻辑移至
has_permission方法(DRF权限类的标准方法); - 增加
view.queryset的存在性校验,避免异常; - 修正
is_admin为is_staff(Django用户模型默认字段); - 使用f-string简化权限代码拼接。
三、同目录相对导入的问题
你用from .permissions import My_has_permission在ss.py中报错,是因为直接运行ss.py时,它被当作顶层脚本,没有父包上下文,相对导入无法识别父包。解决方法:
- 改用绝对导入:
from core.permissions import My_has_permission; - 不要直接运行
ss.py,通过项目入口(如manage.py)触发相关代码,让文件处于包的上下文环境中。
总结
- DRF全局权限类必须配置绝对导入路径,以应用包名为起始;
- 权限类必须遵循DRF规范,将逻辑放在指定方法内;
- 同目录导入优先使用绝对路径,避免相对导入的上下文限制。
内容的提问来源于stack exchange,提问作者Farhang Amaji
相关产品推荐
相关产品推荐

