Martin Taleski
Martin Taleski

Reputation: 6448

Enforcing row level permission in Django Models

I am trying to enforce row (object) level permissions in Django, on the model level.

All the resources on the web revolve around two possible solutions:

Option 1. Passing the request manually to a custom manager with a for_user() method:

    # manager
    class EntryManager(models.Manager):
       def for_user(self, user):
           return self.get_queryset().filter(owner=user)

    # model
    class Entry(models.Model):
        owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
        objects = EntryManager()

    # usage in views/serializers/forms/admin/...
    Entry.objects.for_user(request.user)

Option 2: Using threading.local() variables to store the request/user in the middleware, and than access them in the model.

Examples: https://github.com/citusdata/django-multitenant

https://github.com/benrobster/django-threadlocals

https://github.com/Alir3z4/django-crequest

https://www.viget.com/articles/multi-tenancy-in-django/

I don't like option 1, because it relies on a developer calling a for_user() method, which can be often forgotten.

There are a lot of people on the internet that don't like option 2, because of the usage of threadlocals and also because of a Django philosophy that models should be request-unaware.

I am coming from a framework such as Laravel which allows access to the Request and User at all levels, so I am puzzled why this is a no-no in Django.

I did take a look at django-guardian as well, but the module seems quite complex, and no easy way to filter out all objects linked to a user. Also from what I got, it could not be implemented on the model level.

QUESTION: My question is, is there any other good way to implement Row Level permissions on the Model level, without relying on developers to pass request objects to the Model Manager?

I have shifted my focus on making the Model Manager unusable unless for_request() is called, but there are pitfalls in that direction as well.

Upvotes: 3

Views: 231

Answers (0)

Related Questions