2

我正在接近我认为正在构建的 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 是这样的:

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

现在任何登录用户都可以更改list_idURL 并访问不同的仪表板。我怎样才能使用户只能查看他们自己的 list_id 的仪表板,而不list_id从 URL 中删除参数?我对 Django 的这一部分还很陌生,我真的不知道该往哪个方向发展。

4

3 回答 3

5

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

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

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

if not request.user == user_list.user:
    response = http.HttpResponse()
    response.status_code = 403
    return response
于 2013-06-06T19:07:35.623 回答
4

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

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)
于 2013-06-08T09:53:34.013 回答
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 - 显式地执行它没有任何问题,但是需要很常见,因此有一个方便的函数来执行它。

于 2013-06-06T19:07:42.743 回答