【问题标题】:Django - Pass related object as variable in user_passes_test mixinDjango - 在 user_passes_test mixin 中将相关对象作为变量传递
【发布时间】:2017-01-13 14:16:17
【问题描述】:

我试图将对象的实例限制为仅对该对象通过 OneToOneField 引用的用户可见。我在 DetailView 上使用“user_passes_test”混合来将 request.user 与 OnetoOne 关系中的用户进行比较。我在 django irc 上得到了一些帮助,这导致我尝试实现 get_object 失败,但我仍然卡住了(我是 Django 和 Python 的新手)。

模型:

class Event(models.Model):     
    client = models.OneToOneField(settings.AUTH_USER_MODEL)

观点:

class EventDetail(UserPassesTestMixin, DetailView):
    model = Event

    def test_func(self):
        if self.request.user == self.model.client:
            return True
        else:
            return False

用户在其自己的应用程序中被引用为 User(AbstractUser)

【问题讨论】:

  • 你是如何使用这个test_func函数的?

标签: python django django-views


【解决方案1】:

如果你使用DetailView,那么你可以在视图中实现get_queryset方法:

class EventDetail(DetailView):
    model = Event

    def get_queryset(self):
        queryset = super(DetalView, self).get_queryset()
        return queryset.filter(client=self.request.user)

这将确保Event 对象仅限于作为客户端的用户。

我不确定您使用什么 URL 来访问事件以及为什么 Event 和 User 之间只有 OneToOne 关系。但是如果它是OneToOne 关系,那么这个实现之后的queryset 将只包含一个对象。 (这可能是也可能不是您访问此事件时使用的主键)。

【讨论】:

  • 我在 ForeignKey 上使用 OneToOne,因为永远只有 1 个事件与 1 个用户关联。
  • (我没有意识到按回车键保存了评论!) - url 正在使用 pk 调用 Event 对象,例如:localhost:8000/events/3 - 所以我仍然不确定如何使用 get_queryset 的输出在测试函数中。
  • 我现在看到您的解决方案替换了测试功能,并且效果很好!但我正在使用测试功能,因此我还可以提供一个 if / else 条件,允许标记为“员工”的用户也可以查看该对象。如果用户是员工,使用您的解决方案如何进行功能检查和允许?
  • 您的意思是登录并与事件相关的用户或任何员工用户都可以看到这个对象吗?
  • 是的,完全正确 - 添加 if /else 检查 is_staff 的解决方案似乎工作正常(除非有某些原因导致它不好!)
【解决方案2】:

我终于明白了,我想我写出来后才意识到我可以像这样在查询集上放置一个 if / else 条件:

def get_queryset(self):
    queryset = super(DetailView, self).get_queryset()
    if self.request.user.is_staff:
        return queryset
    else:
        return queryset.filter(client=self.request.user)

谢谢AKS!

【讨论】:

    猜你喜欢
    • 2020-06-13
    • 1970-01-01
    • 2018-10-04
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多