如何限制网站用户查看其他用户资料?

时间:2020-06-29 19:20:34

标签: django django-views django-templates

我在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."

但是它似乎不起作用。我重新启动了服务器。

有什么想法我做错了吗?

1 个答案:

答案 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