Skip to main content
 首页 » 编程设计

python之如何防止用户在 Django DetailView 中看到不属于自己的数据

2024年12月31日21飞鱼

我有一个网络应用程序,用户可以在其中登录并开始输入 ToDoList 的项目. base.html包裹在 is_authenticated 中检查以便用户在登录之前看不到应用程序中的任何内容。我正在做一些测试:

  • 登录为User2
  • 添加一个新的 ToDoListItem
  • 重定向到 DetailView
  • 在本例中,URL = http://localhost:8000/to_do_list/to_do_item/72

此时我意识到 DetailView 将允许 User2查看任何 ToDoListItem 的详细信息对于 User1只需输入现有的 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'), 

View .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. >??? (我还不知道比上面更好的东西)

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

请您参考如下方法:

您也可以通过覆盖 get_queryset method [Django-doc] 在 DetailView 中过滤 :

from django.contrib.auth.mixins import LoginRequiredMixin 
 
class ToDoListItemDetail(<b>LoginRequiredMixin,</b> DetailView): 
 
    model = ToDoListItem 
 
    def <b>get_queryset</b>(self, *args, **kwargs): 
        return super(ToDoListItemDetail, self).get_queryset( 
            *args, **kwargs 
        ).filter(user=self.request.user)

Django 将在幕后始终调用 get_queryset(..)。默认情况下,此函数返回您为所有对象指定的 model 的查询集。但是您因此可以进一步过滤它。

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

在这里添加 LoginRequiredMixin [Django-doc] 也是有意义的到你的类(class),因为万一用户没有登录,你可能想将 hem/her 重定向到登录屏幕。