2012-01-18 101 views
0

我有一个模型,我想基于用户的身份验证级别来限制对对象的访问。匿名用户只能看到对象的一个​​子集,而授权用户可以访问所有对象。通过django书籍阅读,我发现我可以在我的视图中使用像is_authenticated()这样的检查,并根据这种情况实现我的逻辑。但我不希望这些检查散布在我的代码上,而是希望能够给我的模型一些智能:模型应该只提供对当前用户的权限可见的对象。限制模型级别的Django访问

这里有一对夫妇的车型我的工作:

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(“集合”,扁= TRUE) .distinct() - 在这种情况下,我只想检查用户有权查看的那些集合id(即public/private/semi-private)。

是否有可能或者必须将授权逻辑放入我的视图中?

回答

0

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

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

看到这个答案:

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/

而且,这只是为了清楚 - 代码本身并没有住在你的意见,但最终将需要涉及请求对象这样或那样的,所以你将不得不呼叫它从你的视图。

+0

我相信这是'控制器'部分来自术语模型视图控制器的地方。这应该存在于视图中,或者存在于视图可以用其上下文调用的一组单独的逻辑中。你真的不想用一堆视图特定的逻辑来混淆你的模型。 – jdi 2012-01-18 15:20:32

+0

没有试图逆势,但我不明白为什么。当然,从纯粹的角度来看,混合的东西是不好的。但是我使用Django进行web应用程序的开发,并且我认为将它反映到我的模型中并不合适。例如,通常不会在模型定义中拥有生成对象的URL的方法。为什么我们不能使用“请求访问我”方法的相同逻辑? – AdamKG 2012-01-18 15:28:02

+0

感谢您的链接,我会研究子类化QuerySet。 – user1100778 2012-01-18 15:37:00

1

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

模型作业是为数据库提供数据访问层。然后,您可以创建任意数量的视图,以您想要的方式可视化数据。如果您需要匿名数据视图,请创建一个视图来检查用户是否已通过身份验证,并适当地格式化数据。