首页 > 解决方案 > 带有 get_object 的 UserPassesTestMixin 的 test_func 不适用于 ListView

问题描述

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

视图.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 中未解决的引用我确定我做错了什么,但我找不到我的错误。请知道的人指正!谢谢

标签: pythondjangodjango-class-based-views

解决方案


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方法。


推荐阅读