如何根据链接到用户的模型(而不是基于用户组)设置 Django 权限?

Posted

技术标签:

【中文标题】如何根据链接到用户的模型(而不是基于用户组)设置 Django 权限?【英文标题】:How do you set Django permissions based on models linked to a user (and not based on a user's group)? 【发布时间】:2016-02-29 23:07:23 【问题描述】:

我必须建立一个系统,允许用户根据初始调查是否被接受逐步填写调查。

这意味着在用户登录后,他们需要能够填写初步调查以进行筛选。只有在此初步筛选调查获得管理用户(超级用户)的批准后,该用户才能访问第二次(也是最终)调查。

我有一个如下所示的调查模型:

class Screening_survey(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField(max_length=20)
    surname = models.Charfield(max_length=20)
    salary = models.IntegerField()
    is_accepted = models.NullBooleanField()

当用户发布此初始调查时,他们只填写姓名、姓氏和薪水字段。最初发布调查时,“用户”设置为当前登录用户 (request.user),并且 is_accepted 在后台自动设置为“未知”。然后由管理超级用户将 is_accepted 值更改为“是”或“否”。

如果特定用户表单的 is_accepted 字段的值设置为 yes,则该用户应该能够访问下一个调查。

我查看了 Django 权限,但我不认为默认权限对我有用,因为我不希望特定 /group/ 的用户访问特定页面;相反,我希望初始调查已获批准的用户能够访问下一个视图(最终调查)。

我还考虑了 @user_passes_test 装饰器,但它似乎只根据用户检查权限,而不是根据用户和链接到他们的模型。

我知道这个问题看起来很简单——我对 Django 以及一般编程都很陌生)。

感谢您的帮助。

【问题讨论】:

【参考方案1】:

您在现场 - 您需要定义自己的逻辑来查看用户是否已获得批准,而不是权限。权限实际上不允许您以您正在寻找的方式在每个用户或每个模型的基础上进行测试。

有两个地方可以定义这个测试的位置。无论是在视图本身中,还是通过您自己的 @user_passes_test 装饰器。您已经拥有用户对象的外键,因此您可以在视图中编写测试,如下所示:

@login_required
def survey_view(request):
    survey = Screening_survey.objects.filter(user=request.user)
    if survey and survey.is_accepted is 'yes':
        # Do the remaining view logic
    else:
        raise PermissionDenied

如果您想将此逻辑放在@user_passes_test 中,那也可以。用户对象直接传递(见docs的例子)

【讨论】:

谢谢特里斯坦。这看起来好像会起作用。我会尽快实施并支持您的回答。 谢谢,特里斯坦。逻辑是正确的。但是,我确实收到了一个错误,指出 QuerySet (Screening_survey) 没有属性“is_accepted”。我稍微重写了它,然后它起作用了:如果 Screening_survey.objects.filter(user=request.user, is_accepted="Yes"): [其余逻辑如下]。不过,逻辑很好!

以上是关于如何根据链接到用户的模型(而不是基于用户组)设置 Django 权限?的主要内容,如果未能解决你的问题,请参考以下文章

Rails,使用隐藏字段设置用户角色

如何根据用户的身份控制何时在视图中显示删除的链接

根据其ID获取对象

基于hbase进行用户画像查询

如何更改 laravel 中的用户模型以使用其他表进行身份验证而不是用户?

PHP,Codeigniter:如何在Web应用程序中根据用户时区/位置设置日期/时间?