我在Django中为我的网站创建了一些用户,我希望每个用户只能访问自己的个人资料页面。
用户个人资料页面的模板是通过称为UserDetailView
的CBV详细信息视图获取的,该视图附加到包含用户URL的URL上,并且只有在通过身份验证(用户登录)后,页面才会加载。到目前为止一切顺利。
urls.py:
from django.conf.urls import url
from django.urls import path
from basicapp import views
from django.contrib.auth.decorators import login_required
app_name='basicapp'
urlpatterns = [
url(r'^$',views.index,name='index'),
url(r'^user_list/',views.UserView.as_view(),name='user_list'),
url(r'^course_list/',views.CourseView.as_view(),name='course_list'),
url(r'^user_detail/(?P<pk>[-\w]+)/$',views.UserDetailView.as_view(),name='user_detail'),
]
问题出在我登录并获得用户详细信息页面后:如果手动更改URL中的<pk>
,则会加载其他用户配置文件页面。我不希望那样发生。
例如,登录用户配置文件的URL是:
http://127.0.0.1:8000/basicapp/user_detail/1/
在用户已经登录的情况下,我将URL手动更改为:
http://127.0.0.1:8000/basicapp/user_detail/2/
,并且有效。它应该使我退缩或向我显示错误消息
我尝试使用LoginRequiredMixin
views.py:
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.utils.decorators import method_decorator
class UserDetailView(LoginRequiredMixin,DetailView):
context_object_name='user_detail'
model=models.User
template_name='basicapp/user_detail.html'
raise_exception = True # Raise exception when no access instead of redirect
permission_denied_message = "This page dows not exist."
,我也尝试使用method_decorator
:
@method_decorator(login_required)
class UserDetailView(LoginRequiredMixin,DetailView):
context_object_name='user_detail'
model=models.User
template_name='basicapp/user_detail.html'
raise_exception = True # Raise exception when no access instead of redirect
permission_denied_message = "This page dows not exist."
但是它似乎不起作用。我重新启动了服务器。
有什么想法我做错了吗?
答案 0 :(得分:1)
LoginRequiredMixin
将确保您仅在登录后才能看到该页面,但这并不意味着您必须是该用户。
但是,如果您只能看到自己的个人资料,则无论如何都不能在url
中添加主键,您只需将URL定义为:
url(r'^user_detail/$', views.UserDetailView.as_view(), name='user_detail'),
然后在视图中返回.get_object()
method [Django-doc]的登录用户:
class UserDetailView(LoginRequiredMixin,DetailView):
context_object_name='user_detail'
model=models.User
template_name='basicapp/user_detail.html'
def get_object(self, *args, **kwargs):
return self.request.user
或者您可以通过过滤查询集来限制用户:
path('^user_detail/<int:pk>/', views.UserDetailView.as_view(), name='user_detail'),
class UserDetailView(LoginRequiredMixin,DetailView):
context_object_name='user_detail'
model=models.User
template_name='basicapp/user_detail.html'
def get_queryset(self, *args, **kwargs):
qs = super().get_queryset(*args, **kwargs)
if not self.request.user.is_superuser:
qs = qs.filter(pk=self.request.user.pk)
return qs