更好地使用第三方行级权限应用程序或在Django视图中筛选查询结果?

时间:2012-11-09 15:39:08

标签: django permissions django-permissions django-guardian

我正在编写一个涉及文档创建的Django应用程序。我有一些要求:

  1. 检查用户是否能够查看任何文档。
  2. 如果允许用户查看文档,则只允许他们查看他们有权访问的文档。
  3. 我提出了两个解决方案,我想知道一个人在哲学上/实际上是否比另一个好。

    我提出的两个解决方案是:

    解决方案一(使用第三方Django-Guardian)

    Models.py

    class Document(models.Model)
        owner = models.ForeignKey(User)
        document_name = models.CharField(max_length=60)
        document_content = models.TextField()
    
        class Meta:
        permissions = (
            ('view_document', 'View Document'),
        )
    

    views.py

    @permission_required('document.view_document', (Document, 'pk', 'document_id'))
    def view_document(request, document_id):
        document = Document.objects.get(pk=document_id)
        return render_to_response("native/view_events.html",
        {
            'document' : document,
        }, context_instance=RequestContext(request))
    

    我看到第一个解决方案的缺点是我必须在每次创建对象时显式设置权限,而且我必须两次点击数据库:一次检查权限并再次检索文档对象。

    解决方案二(使用内置Django权限)

    Models.py

    class Document(models.Model)
        owner = models.ForeignKey(User)
        document_name = models.CharField(max_length=60)
        document_content = models.TextField()
        viewers = models.ManyToManyField(User)
    
        class Meta:
        permissions = (
            ('view_document', 'View Document'),
        )
    

    views.py

    @permission_required('document.view_document')
    def view_document(request, document_id):
        document = Document.objects.filter(pk=document_id, viewers__pk=request.user.pk)[0]
        return render_to_response("native/view_events.html",
        {
            'document' : document,
        }, context_instance=RequestContext(request))
    

    我看到第一个解决方案的缺点是我必须做两次检查,一次检查是否能够查看文档,还有一次检查是否可以查看特定文档。另一方面,如果我有一个管理员,我希望能够查看所有文档,我不需要明确授予每个文档的权限;我可以给他'查看文件'的许可。

    似乎两种解决方案各有利弊。理论/实践中是否有更好的理由?

1 个答案:

答案 0 :(得分:0)

我发现第二种方法更好。因为,您可以检查对象的模型级别权限。虽然在第一个我猜,你应该能够完成类似的事情。我不确定,但是django-guardian提供了一种方法来检查视图代码中的权限而不是装饰器。您可以手动检查模型级权限。 例如,

def view_doc(request, doc_id):
      if user can not view doc: #Model Level Permission
              return HttpResponse("Sorry can not view")
      if check django-guardian permission #Object Level Permission
               return HttpResponse("Can not view doc")
      #further code

但是我会建议第二种方法,因为你可以创建一个api来检查权限并定制它更具可扩展性。