【问题标题】:In django, how can I ensure that a specific user is accessing a view?在 django 中,如何确保特定用户正在访问视图?
【发布时间】:2019-08-20 08:31:52
【问题描述】:

我希望能够检查访问页面的用户是否是特定用户。

例如,当用户访问我的博客应用上的“编辑帖子”页面时,我想确保该用户是帖子的作者。

目前,我检查访问“/Blog/Edit//”的用户是否具有 blog.change_post 权限。

但是,如果第二个用户(也拥有该权限)输入 URL 以更改其他人的帖子,他们将通过该权限检查并能够编辑其他人的帖子。

我想要的是一个 @user_passes_test 函数,它检查用户对象是否根据帖子的作者属性访问视图。

#/Blog/urls.py

urlpatterns = [
    ...
    path('Edit/<int:pk>', views.BlogEdit, name='BlogEdit'),
    ...
]



#/Blog/views.py

@permission_required('blog.change_post', login_url='/Portal/login')
def BlogEdit(request, pk):
post = get_object_or_404(Post, pk=pk)
    if request.method == "POST":
        form = PostForm(request.POST, instance=post)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            return redirect('/Blog', pk=post.pk)
    else:
        form = PostForm(instance=post)
    return render(request, 'Blog/Edit.html', {'form': form})

【问题讨论】:

    标签: python django authentication


    【解决方案1】:

    您可以在get_object_or_404 中添加一个额外的过滤器:

    @permission_required('blog.change_post', login_url='/Portal/login')
    def BlogEdit(request, pk):
        post = get_object_or_404(Post, pk=pk, author=request.user)
        if request.method == "POST":
            form = PostForm(request.POST, instance=post)
            if form.is_valid():
                form.save()
                return redirect('/Blog', pk=post.pk)
        else:
            form = PostForm(instance=post)
        return render(request, 'Blog/Edit.html', {'form': form})

    这里的author 是从Post 到用户模型的假设ForeignKey。可能名字不同,但思路还是一样的。

    因此,这意味着如果pkBlogpk,而request.user 不是 author,那么我们将得到404 响应。

    这里过滤的优点是我们使用单个查询进行过滤。我们不会(懒惰地)加载author 来检查它是否与登录用户相同。

    注意post = form.save(commit=False)post.save()等价于post = form.save()(所以commit=True)。

    【讨论】:

    • 我喜欢这个,很干净。谢谢!
    【解决方案2】:

    在基于类的视图中,将get_queryset 方法更改为按当前用户进行过滤。

    class MyView(LoginRequiredMixin, UpdateView):
        ...
    
        def get_queryset(self):
            """
            Only the current logged in user can edit ... 
            """
            return super().get_queryset().filter(created_by=self.request.user)
    

    【讨论】:

      【解决方案3】:

      最后我是从This Post 弄明白的。 urbanspaceman 建议适用于基于类的视图,但对于基于功能的视图,您可以这样做:

      @permission_required('blog.change_post', login_url='/Portal/login')
      def BlogEdit(request, pk):
          post = get_object_or_404(Post, pk=pk)
      
          if post.author != request.user:
              raise Http404("You are not allowed to edit this Post")
      
          # ... Rest of view here ... #
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-20
        • 1970-01-01
        • 1970-01-01
        • 2020-02-17
        • 1970-01-01
        • 1970-01-01
        • 2016-02-21
        • 2021-04-27
        相关资源
        最近更新 更多