Django一对一关联自定义用户类型视图层角色校验报错解决方法问询
Django 多角色用户校验的合理实现方案
现有写法直接调用Model.objects.get(),当对应角色的关联数据不存在时会抛出未捕获的DoesNotExist异常,触发500错误,以下是几种可落地的优化方案:
方案1:使用exists()做存在性校验
适合需要自定义错误返回逻辑的场景,不会抛出异常,直接返回布尔值判断角色,且仅做存在性查询性能更高:
# 校验是否为学生 is_student = Student.objects.filter(pk=request.user.id).exists() # 校验是否为教师 is_teacher = Teacher.objects.filter(pk=request.user.id).exists() if not is_student: # 自定义返回无权限逻辑,比如返回403 return JsonResponse({"msg": "仅学生可访问该接口"}, status=403)
方案2:使用get_object_or_404快捷方法
如果接口允许查询不到角色直接返回404,可以用Django内置的快捷方法自动处理异常:
from django.shortcuts import get_object_or_404 # 学生身份校验,不存在直接返回404 student = get_object_or_404(Student, pk=request.user.id)
方案3:封装自定义权限校验工具/装饰器
推荐优先使用该方案,复用性更高,代码更整洁
如果多个接口都需要做角色校验,可以封装成装饰器避免重复代码:
from functools import wraps from django.http import JsonResponse def student_required(view_func): @wraps(view_func) def wrapper(request, *args, **kwargs): if not Student.objects.filter(pk=request.user.id).exists(): return JsonResponse({"msg": "无权限访问"}, status=403) return view_func(request, *args, **kwargs) return wrapper # 视图函数直接加装饰器即可 @student_required def create_homework(request): # 业务逻辑 ...
如果使用Django REST Framework,还可以自定义权限类:
from rest_framework.permissions import BasePermission class IsStudent(BasePermission): def has_permission(self, request, view): return Student.objects.filter(pk=request.user.id).exists() # 视图中指定权限类 class CreateHomeworkView(APIView): permission_classes = [IsStudent] ...
方案4:给AuthUser扩展角色判断属性
可以通过给Django内置User模型扩展属性的方式,新增角色判断属性,调用更方便:
# 可以放在models.py或者项目初始化加载的文件中 from django.contrib.auth.models import User @property def is_student(self): return hasattr(self, 'student') @property def is_teacher(self): return hasattr(self, 'teacher') User.add_to_class('is_student', is_student) User.add_to_class('is_teacher', is_teacher) # 视图中直接调用即可 if not request.user.is_student: return JsonResponse({"msg": "无权限"}, status=403)
注意:该方式依赖OneToOneField的反向关联特性,hasattr会自动捕获反向关联不存在的异常返回False,逻辑安全可用。
内容的提问来源于stack exchange,提问作者RussianPupok Pupok
相关产品推荐
相关产品推荐

