سؤال

I am writing a Django app that involves the creation of documents. I have a few requirements:

  1. Check to see if the user is able to view any documents at all.
  2. If the user is allowed to view documents, only allow them to view documents they have permission for.

I have come up with two solutions and am wondering if one is philosophically/practically better than the other.

The two solutions I've come up with are:

Solution One (using third-party 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))

The downside I see to solution number one is that I have to explicitly set permissions every time I create an object, plus I have to hit the database twice: once to check permissions and again to retrieve the document object.

Solution Two (using built-in Django permissions)

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))

The downside I see to solution number one is that I have to do two checks, one to see if they are able to view documents at all, and one to see if they can view the particular document. A plus side to this is that if I have an admin that I want to be able to view all documents, I don't need to explicitly grant permission to each one; I can just give him the 'view document' permission.

It seems both solutions have their pros and cons. Is there one that is better in theory/practice?

هل كانت مفيدة؟

المحلول

I find the second approach better. Since, you can check the model level permission on the object. Though in the first I guess, you should be able to accomplish similar things. I am not sure but if django-guardian provides a way to check the permission inside the view code instead of the decorator. You could manually check for Model Level Permission. For example,

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

But I would suggest the second approach since, you can create an api just to check permission and customize it which is more scalable.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top