我尝试做的是检测登录用户的类型,然后将.profile
参数设置为request.user
,这样我就可以通过在视图中调用request.user.profile
来使用它。
为此,我编写了一个Middleware
,如下所示:
class SetProfileMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
user, token = JWTAuthentication().authenticate(request)
profile_type = token.payload.get("profile_type", None)
request.user.profile = User.get_profile(profile_type, request.user)
request.user.profile_type = profile_type
# Works Here
print("-" * 20)
print(type(request.user)) # <class 'django.utils.functional.SimpleLazyObject'>
print('Process Request ->', request.user.profile)
response = self.get_response(request)
# Does not work here
print("-" * 20)
print(type(request.user)) # <class 'users.models.User'>
print('Process Response ->', request.user.profile)
return response
def process_view(self, request, view_func, view_args, view_kwargs):
# Works here
print("-" * 20)
print(type(request.user)) # <class 'django.utils.functional.SimpleLazyObject'>
print('Process View ->', request.user.profile)
现在我可以在process_view
中访问request.user.profile
,但它不存在于我的视图中,并导致AttributeError
声明'User' object has no attribute 'profile'
。
似乎我的request.user
是被覆盖的地方之前击中的看法。
请注意,我使用的是Django Rest框架,以下是我的观点:
class ProfileAPIView(generics.RetrieveUpdateAPIView):
serializer_class = ProfileSerializer
def get_object(self):
obj = self.request.user.profile # Raise the `AttributeError`
self.check_object_permissions(self.request, obj)
return obj
下面是我的settings.py
:
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
LOCAL_MIDDLEWARE = [
"users.middleware.SetProfileMiddleware",
]
MIDDLEWARE = MIDDLEWARE + LOCAL_MIDDLEWARE
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
"DEFAULT_RENDERER_CLASSES": (
"rest_framework.renderers.JSONRenderer",
"rest_framework.renderers.BrowsableAPIRenderer",
),
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework_simplejwt.authentication.JWTAuthentication",
],
}
SIMPLE_JWT = {
"SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(minutes=45),
"AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.SlidingToken",),
}
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
AUTH_USER_MODEL = "users.User"
LOGIN_REDIRECT_URL = "admin/"
2条答案
按热度按时间elcex8rz1#
问题是您无法将新属性添加到
User
类。而是尝试将属性直接添加到请求中,如下所示
request.user_profile = User.get_profile(profile_type, request.user)
然后在基于函数的视图中:
基于函数的视图和基于类的视图之间的唯一区别是装饰器将接收
request
参数而不是self
。您的类应如下所示:
lrpiutwd2#
在花了几个小时弄清楚发生了什么之后,发现SimpleJWT的
JWTAuthentication.authenticate()
方法在请求到达视图之前被调用,覆盖了request.user
属性。因此,我没有尝试使用中间件将概要文件添加到
request.user
,而是结束了对JWTAuthentication.authentication()
方法的定制:settings.py
: