我的项目中有两个用户模型:
class User(AbstractUser):
id = models.AutoField(primary_key=True)
email = models.EmailField(unique=True)
...
class ProjectMember(UserModel):
project = models.ForeignKey("project.Project")
我使用djangorestframework-simplejwt
进行授权,它在视图中的request.user
中为我提供了一个User
实例,下面是一个示例:
from rest_framework.permissions import IsAuthenticated
from rest_framework.request import Request
from rest_framework.views import APIView
class CurrentUserView(ListAPIView):
permission_classes = [IsAuthenticated]
def get(self, request: Request):
# there will be User instance
current_user = request.user
# Will raise an exception
current_user.project
# some other code here
...
我有一个用户,但我不能访问project
,因为它在ProjectMember
中定义,不能通过User
访问。
我发现我可以通过检查特殊属性来获得ProjectMember实例:
def get(self, request: Request):
# there will be ProjectMember instance
current_user = request.user.projectmember
# I can access project now
current_user.project
# some other code here
...
但现在我必须在我使用当前用户的每个视图中重复此代码。如何覆盖request.user
使其始终为ProjectMember
(当然,如果它是ProjectMember
的实例(?
我在写问题时找到了解决方案。
覆盖JWTAuthentication
,如下所示:
# users/auth/custom_auth.py
from rest_framework_simplejwt.authentication import JWTAuthentication
class CustomAuth(JWTAuthentication):
def authenticate(self, request):
user, access = super().authenticate(request)
if hasattr(user, 'projectmember'):
user = user.projectmember
return user, access
在settings.py
中更改:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication'
],
}
到新类的路径(在我的情况下为users/auth/custom_auth.py:CustomAuth
(:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'users.auth.custom_auth.CustomAuth'
],
}