Django - 允许用户只查看自己的页面

时间:2013-06-06 19:05:24

标签: python django django-views django-urls

我正在接近我认为正在构建的Django应用程序的开发结束。此应用程序中的关键视图是用户仪表板,用于显示某种指标。基本上我不希望用户能够看到其他用户的仪表板。现在我的观点看起来像这样:

@login_required
@permission_required('social_followup.add_list')
def user_dashboard(request, list_id):
    try:
        user_list = models.List.objects.get(pk=list_id)
    except models.List.DoesNotExist:
        raise Http404
    return TemplateResponse(request, 'dashboard/view.html', {'user_list': user_list})

此视图的网址如下:

url(r'u/dashboard/(?P<list_id>\d+)/$', views.user_dashboard, name='user_dashboard'),

现在,任何已登录的用户都可以更改URL中的list_id并访问其他信息中心。我怎样才能使用户只能查看自己的list_id的仪表板,而无需从URL中删除list_id参数?我对Django的这一部分很新,并且不知道要进入哪个方向。

3 个答案:

答案 0 :(得分:5)

只需拉request.user并确保此列表是他们的。

您没有描述过您的模型,但它应该是直截了当的。

也许您的List模型中存储了用户ID?在那种情况下,

if not request.user == user_list.user:
    response = http.HttpResponse()
    response.status_code = 403
    return response

答案 1 :(得分:3)

我用可重复使用的mixin解决了类似情况。您可以通过方法装饰器为调度方法添加login_required,也可以在视图的urlpatterns中添加。

class OwnershipMixin(object):
    """
    Mixin providing a dispatch overload that checks object ownership. is_staff and is_supervisor
    are considered object owners as well. This mixin must be loaded before any class based views
    are loaded for example class SomeView(OwnershipMixin, ListView)
    """
    def dispatch(self, request, *args, **kwargs):
        self.request = request
        self.args = args
        self.kwargs = kwargs
        # we need to manually "wake up" self.request.user which is still a SimpleLazyObject at this point
        # and manually obtain this object's owner information.
        current_user = self.request.user._wrapped if hasattr(self.request.user, '_wrapped') else self.request.user
        object_owner = getattr(self.get_object(), 'author')

        if current_user != object_owner and not current_user.is_superuser and not current_user.is_staff:
            raise PermissionDenied
        return super(OwnershipMixin, self).dispatch(request, *args, **kwargs)

答案 2 :(得分:0)

您需要存储一些有关用户可以访问的列表或列表的信息,然后将其包含在user_list查找中。让我们假设List有一个所有者,User模型的外键的简单情况。这是列表和用户之间的多对一关系;没有列表由多个用户拥有,但用户可以拥有多个列表。那你想要这样的东西:

try:
    user_list = models.List.objects.get(pk=list_id, owner=request.user)
except models.List.DoesNotExist:
    raise Http404

是否返回404或403在某种程度上是意见问题; 403的定义说:

  

如果请求方法不是HEAD并且服务器希望公开为什么请求未被满足,则它应该描述实体中拒绝的原因。如果服务器不希望将此信息提供给客户端,则可以使用状态代码404(未找到)。

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4

如果你确实返回了404,你可以使用django快捷键功能get_object_or_404而不是显式的try / except - 明确地执行它没有任何问题,但是需要很普遍,那就是& #39;这是一个方便的功能。