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

如何在djangorestframework-simplejwt中重写request.user为ProjectMember

解决request.user自动返回ProjectMember实例的方案

下面提供两种可落地的实现方式,避免在每个视图中重复编写转换逻辑:

方法一:重写SimpleJWT认证后端

利用simplejwt的认证流程,在获取用户后自动替换为ProjectMember实例(如果存在的话)。

  1. 创建自定义认证类
# 在你的app下新建authentication.py
from rest_framework_simplejwt.authentication import JWTAuthentication
from .models import ProjectMember

class CustomJWTAuthentication(JWTAuthentication):
    def authenticate(self, request):
        # 调用父类方法完成基础JWT认证,拿到User实例和token
        user, token = super().authenticate(request)
        
        if user and user.is_authenticated:
            # 尝试获取关联的ProjectMember,不存在则保留原User实例
            try:
                project_member = ProjectMember.objects.get(user=user)
                user = project_member
            except ProjectMember.DoesNotExist:
                pass
        
        return user, token
  1. 在settings.py中配置DRF使用自定义认证类
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'your_app.authentication.CustomJWTAuthentication',
        # 保留其他需要的认证类
    ],
}

方法二:使用Django中间件

通过中间件在请求到达视图前修改request.user对象。

  1. 创建自定义中间件
# 在你的app下新建middleware.py
from django.utils.deprecation import MiddlewareMixin
from .models import ProjectMember

class ProjectMemberMiddleware(MiddlewareMixin):
    def process_request(self, request):
        # 仅处理已认证的用户
        if request.user.is_authenticated:
            try:
                project_member = ProjectMember.objects.get(user=request.user)
                request.user = project_member
            except ProjectMember.DoesNotExist:
                pass
  1. 在settings.py中注册中间件(注意顺序,需放在认证中间件之后)
MIDDLEWARE = [
    # 其他系统中间件...
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'your_app.middleware.ProjectMemberMiddleware',
    # 其他自定义中间件...
]

关键注意事项

  • 如果一个User对应多个ProjectMember,上述代码的get()会抛出MultipleObjectsReturned异常。这种场景下,需要补充逻辑(比如从URL参数、请求头中获取当前项目ID,过滤出对应ProjectMember)。
  • 建议将ProjectMember与User的关联改为OneToOneField,避免多实例问题:
class ProjectMember(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='projectmember')
    project = models.ForeignKey("project.Project", on_delete=models.CASCADE)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 00:05:20