test_func 对于带有 get_object 的 UserPassesTestMixin 不适用于 ListView

test_func for UserPassesTestMixin with get_object does not work with ListView

在我的项目仪表板的联系人部分,保存的联系人仅对作者可见,但之前所有人都可以看到,因为我忘记在 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 中未解析的引用 我确定我做错了什么,但我找不到我的错误。请知道的朋友指正!谢谢

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 时才有效。您可以改进 mixin,但您可能更愿意重复 get_queryset 方法。