2

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

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

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

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

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

我看到解决方案一的缺点是我必须进行两项检查,一项是查看他们是否能够查看文档,另一项是查看他们是否可以查看特定文档。这样做的好处是,如果我有一个管理员希望能够查看所有文档,我不需要明确授予每个文档的权限;我可以给他“查看文档”的权限。

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

4

1 回答 1

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 来检查权限并对其进行自定义,使其更具可扩展性。

于 2012-11-09T16:30:54.357 回答