我有一个模型,我想根据用户的身份验证级别限制对对象的访问。匿名用户只能看到对象的子集,而授权用户可以访问所有对象。通读 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有权查看(即公共/私人/半私人)。
是否可以或者我必须将授权逻辑放入我的视图中?
将身份验证放在模型上对于这种逻辑来说是错误的地方。视图正是这个逻辑存在的正确位置,这就是为什么 django 提供了各种 auth 装饰器来保护视图,例如 login_required()
模型的工作是提供对数据库的数据访问层。然后,您可以创建任意数量的视图,以您想要的方式可视化数据。如果您需要数据的匿名视图,请创建一个视图来检查用户是否经过身份验证,并适当地设置数据格式。
请注意,在您给出的查询示例中 (
Image.objects.values_list('collection',flat=True).distinct()
),从未提及 request
- 那么该查询如何能够检查当前用户?
但这并不意味着您必须在视图中执行此操作 - 您可以向模型本身添加方法,甚至可以子类化 QuerySet 以添加一个方法来检查当前请求,例如
.filter(foo=bar).allowed_for_user(user)
。
看到这个答案:
https://stackoverflow.com/a/4576649/16361
这确实链接到您的一篇古老的博客文章,尽管我似乎已经破坏了该答案中的链接,抱歉 - 正确的网址是:
编辑:删除由 NSFW 内容接管的域和死链接。
另外,为了说清楚 - 代码本身不必存在于您的视图中,但最终需要以一种或另一种方式涉及请求对象,因此您必须从您的视图中call它。