最好使用第三方行级权限应用程序或在Django视图中过滤查询结果



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

  1. 检查用户是否能够查看任何文档。
  2. 如果允许用户查看文档,则只允许他们查看已许可的文档。

我提出了两种解决方案,想知道一个解决方案在哲学上/实际上比另一个更好。

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

解决方案ONE (使用第三方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))

我认为解决方案第一的缺点是我必须进行两次检查,一个检查他们是否能够查看文档,一个查看他们是否可以查看特定文档。加利的一面是,如果我有一个我希望能够查看所有文档的管理员,则我不需要明确授予每个文档的许可;我可以授予他"查看文件"许可。

似乎两种解决方案都有其优点和缺点。在理论/实践中有更好的吗?

我发现第二种方法更好。因为,您可以在对象上检查模型级别的权限。尽管我想在第一个,但您应该能够完成类似的事情。我不确定,但是如果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只是为了检查许可并自定义更可扩展的API。

最新更新