使用get_object的UserPassesTestMixin的test_func不适用于ListView

时间:2019-04-11 09:18:37

标签: python django django-class-based-views

在我的项目的仪表板的“联系人”部分中,保存的联系人仅对作者可见,但以前对所有人都是可见的,因为我忘记了在CBV中包含UserPassesTestMixin。我包括了,但是浏览器向我显示了名为NotImplemented test_func的错误,我也实现了test_func

views.py

class ContactListView(LoginRequiredMixin, UserPassesTestMixin, ListView):
   model = ClientContact
   template_name = 'site/contacts.html'
   context_object_name = 'contacts'
   ordering = ['created_at', '-updated_at']

   def test_func(self):
       contact = self.get_object()
       if self.request.user == contact.author:
          return True
       return False

它又说NotImplemented test_func和get_oject是ListView中一个未解决的引用 我确定我做错了什么,但是我找不到我的错误。如果有人知道这一点,请纠正我!谢谢

1 个答案:

答案 0 :(得分:1)

ListView用于显示多个对象,因此调用get_object()(用于单个对象(如DetailView)的视图没有意义。

列表视图的常用方法是覆盖get_queryset,并过滤查询集以仅显示该用户的对象。

class ContactListView(LoginRequiredMixin, ListView):
    model = ClientContact
    template_name = 'site/contacts.html'
    context_object_name = 'contacts'
    ordering = ['created_at', '-updated_at']

    def get_queryset(self):
        return super(ContactListView, self).get_queryset().filter(author=self.request.user)

您已经拥有LoginRequiredMixin,它将在用户未登录时处理该情况。

如果要在多个列表视图中过滤查询集,则可以编写一个mixin,例如:

class AuthorMixin(object):
    def get_queryset(self):
        return super(AuthorMixin, self).get_queryset().filter(author=self.request.user)

然后在您的视图中将其用作:

class ContactListView(LoginRequiredMixin, AuthorMixin, ListView):
    ...

请注意,以上内容未经测试,需要LoginRequiredMixin(因为它不能处理匿名用户的情况),并且仅在用户外键名为author时才有效。您可以改善混合效果,但是您可能更愿意重复使用get_queryset方法。