代码之家  ›  专栏  ›  技术社区  ›  Scott Skiles

如何防止用户在Django DetailView中看到不属于他们的数据?

  •  2
  • Scott Skiles  · 技术社区  · 6 年前

    我有一个web应用程序,用户在其中登录并开始输入项目 ToDoList . 这个 base.html is_authenticated 选中此复选框,以便用户在登录之前无法看到应用程序中的任何内容。我在做一些测试:

    • 以身份登录 User2
    • ToDoListItem
    • DetailView
    • 在本例中,URL= http://localhost:8000/to_do_list/to_do_item/72

    此时我意识到DetailView将允许 查看详细信息 托多利斯蒂姆 对于 User1 只要进入一个现有的 pk 分为: http://localhost:8000/to_do_list/to_do_item/<int:pk> .

    url.py包含

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

    视图.py

    class ToDoListItemDetail(DetailView):
        model = ToDoListItem
    

    todolistitem\u 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. 我可以检查登录的用户的名称是否与拥有 托多利斯蒂姆 .
    3. 我可以重写 get_context_data() 对于DetailView并在那里检查用户所有权(类似于no.1,但在DetailView中)
    4. ??? (还有比上面更好的东西我还不知道)

    2 回复  |  直到 6 年前
        1
  •  1
  •   willeM_ Van Onsem    6 年前

    你可以 滤波器 DetailView 同样,通过覆盖 get_queryset method [Django-doc]

    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)

    Django会一直在窗帘后面打电话 get_queryset(..) . 默认情况下,此函数返回 model 您指定了所有对象。但是你可以进一步过滤。

    get_object method [Django-doc] 然后用 id slug ,但如果已筛选出不属于 self.request.user

    在这里添加 LoginRequiredMixin [Django-doc] 如果用户没有登录,您可能需要将hem/her重定向到登录屏幕。

        2
  •  0
  •   Alberto Arzuaga Torres    6 年前

    有一个名为的权限:¨可以阅读¨ 允许您处理访问。例如:

    class FruitEdit(PermissionRequiredMixin,DetailView):
          permission_required = 'app.read_fruit'
          ...