在模型级别限制django中的访问

时间:2012-01-18 15:09:51

标签: django django-models django-views

我有一个模型,我想根据用户的身份验证级别限制对象的访问。匿名用户只能看到对象的子集,而授权用户可以访问所有对象。通过阅读django书,我发现我可以在视图中使用is_authenticated()等检查,并根据该条件实现我的逻辑。但是我不希望这些检查霰弹枪遍布我的代码,而是我希望能够为我的模型提供一些智能:模型应该只提供当前用户权限可见的对象。

以下是我正在使用的几个模型:

class Collection(models.Model):
    VISIBILITY_CHOICES = (
    ('P', 'Private'),
    ('SP', 'Semi-Private'),
    ('PUB', 'Public')
    )

    name = models.CharField(max_length=40)
    visibility = models.CharField(max_length=3, choices=VISIBILITY_CHOICES)
    category = models.CharField(max_length=50)


class Image(models.Model):
    image = models.ImageField(upload_to= get_upload_to)
    collection = models.ForeignKey(Collection)

我所做的查询的一个例子是:collection_ids = Image.objects.values_list('collection',flat = True).distinct() - 在这种情况下,我只想检查那些那些集合id用户有权查看(即公共/私人/半私人)。

是否可以或者我必须在我的视图中放置授权逻辑?

2 个答案:

答案 0 :(得分:1)

将身份验证放在模型上是这个逻辑的错误位置。视图正是这个逻辑生存的正确位置,这就是为什么django提供各种auth装饰器来保护视图,例如login_required()

模型作业是提供对数据库的数据访问层。然后,您将创建任意数量的视图,以便以您希望的方式显示数据。如果您需要匿名数据视图,请创建一个视图,检查用户是否经过身份验证,并相应地格式化数据。

答案 1 :(得分:0)

请注意,在您提供(Image.objects.values_list('collection',flat=True).distinct())的查询示例中,从未提及request - 那么该查询将如何检查当前用户?

但这并不意味着您必须在视图中执行此操作 - 您可以向模型本身添加方法,甚至可以将QuerySet子类化为添加方法来检查当前请求,例如.filter(foo=bar).allowed_for_user(user)。< / p>

看到这个答案:

https://stackoverflow.com/a/4576649/16361

你真正链接到一篇古老的博客文章,虽然我似乎打破了答案中的链接,抱歉 - 正确的网址是:

http://adam.gomaa.us/blog/2009/feb/16/subclassing-django-querysets/

编辑:一篇较新的文章:

http://zmsmith.com/2010/04/using-custom-django-querysets/

另外,只是为了说清楚 - 代码本身不必存在于您的视图中,但最终需要以某种方式涉及请求对象,因此您必须调用你的观点。