首页 > 解决方案 > 如何防止用户在 Django DetailView 中看到不属于他们的数据?

问题描述

我有一个网络应用程序,用户在其中登录并开始输入ToDoList. 它base.html包含在is_authenticated支票中,因此用户在登录之前看不到应用程序中的任何内容。我正在做一些测试:

在这一点上,我意识到 DetailView 将允许User2查看任何的详细信息ToDoListItemUser1只需将现有的pk输入:http://localhost:8000/to_do_list/to_do_item/<int:pk>

urls.py 包括

path('to_do_item/<int:pk>', views.ToDoListItemDetail.as_view(), name='todo-item-detail'),

视图.py

class ToDoListItemDetail(DetailView):
    model = ToDoListItem

todolistitem_detail.html

{% extends 'base.html' %}
{% block content %}

<a href="/">Home</a>
    <h1>DetailView for 'ToDoListItem' model</h1>
    <p>TaskTitle: '{{ object.title }}'</p>
    <p>Complete: '{{ object.is_complete }}'</p>
    <p>User: '{{ object.user}}'</p> 
{% endblock %}

防止这种情况发生的推荐方法是什么?我正在考虑以下几点:

  1. 我可以完全删除 DetailView 并定向到仅返回用户数据的不同 URL(使用类似的东西ToDoListItem.objects.filter(user=request.user)
  2. 我可以检查登录用户的名称是否与拥有ToDoListItem.
  3. 我可以覆盖get_context_data()DetailView 并在那里检查用户所有权(类似于第 1 号,但在 DetailView 中)
  4. ???(比上面更好的东西我还不知道)

有没有办法限制用户只能在整个应用程序中查看他们自己的数据,而无需在每次需要时都执行此逻辑?

标签: pythondjangodjango-models

解决方案


您也可以通过覆盖方法 [Django-doc]过滤DetailViewget_queryset

from django.contrib.auth.mixins import LoginRequiredMixin

class ToDoListItemDetail(LoginRequiredMixin, DetailView):

    model = ToDoListItem

    def get_queryset(self, *args, **kwargs):
        return super(ToDoListItemDetail, self).get_queryset(
            *args, **kwargs
        ).filter(user=self.request.user)

姜戈总是在窗帘后面打电话get_queryset(..)。默认情况下,此函数返回model您为所有对象指定的查询集。但是您因此可以进一步过滤它。

然后, Django 的get_object方法 [Django-doc]将进一步使用idand/or对其进行过滤slug,但是如果您已经过滤掉了不属于 的元素self.request.user,那么这只会导致查询不返回任何结果。

LoginRequiredMixin在这里将[Django-doc]添加到您的班级也很有意义,因为如果用户没有登录,您可能希望将 hem/her 重定向到登录屏幕。


推荐阅读