首页 > 解决方案 > 如何限制网站用户查看其他用户资料?

问题描述

我在 Django 中为我的网站创建了一些用户,我希望每个用户只能访问他自己的个人资料页面。

用户个人资料页面的模板是通过一个名为UserDetailView附加到包含用户的 URL 的 CBV 详细信息视图获取的,并且该页面仅在身份验证后加载。(用户登录)。到目前为止,一切都很好。

网址.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'),    
   

]

问题是在我登录并获取用户详细信息页面后:如果我手动更改<pk>URL,我会加载其他用户个人资料页面。我不希望这种情况发生。

例如,登录用户配置文件的 URL 是:

http://127.0.0.1:8000/basicapp/user_detail/1/

在用户已经登录的情况下,我手动将 URL 更改为:

http://127.0.0.1:8000/basicapp/user_detail/2/

它有效。它应该限制我或向我显示错误消息

我尝试使用LoginRequiredMixin

视图.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."

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

任何想法我做错了什么?

标签: djangodjango-viewsdjango-templates

解决方案


LoginRequiredMixin将确保您只有在登录后才能看到该页面,但这并不意味着您必须是该用户。

但是,如果您只能看到自己的个人资料,那么url无论如何添加主键没有多大意义,您可以将 url 定义为:

url(r'^user_detail/$', views.UserDetailView.as_view(), name='user_detail'),

然后在视图中返回.get_object()方法 [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

推荐阅读