[Solved]-Object Ownership in Django

17👍

My approach would be adding a method to the model:

class YourModelWithOwnership(models.model):
    ...

    def user_can_manage_me(self, user):
        return user == self.user or user.has_perm('your_app.manage_object')

I’d then call that method whenever a permission check is required, and take some action based on the outcome. So for a view that would be

from django.shortcuts import get_object_or_404
...

def view_func(request, item_id):
    item = get_object_or_404(YourModelWithOwnership, id=item_id) # or whatever is needed to get the object
    if not item.user_can_manage_me(request.user):
        # user not allowed to manage
        ...
    else:
        ...

Later I’d probably realize that that’s still quite some boilerplate code to write in every view that needs that test, so I’d implement an exception that’s thrown when a user can’t manage an object…

class CannotManage(Exception):
    pass

…and add another method to the model:

from django.db import models
from django.shortcuts import get_object_or_404

class YourModelWithOwnership(models.model):
    ...

    @classmethod
    def get_manageable_object_or_404(cls, user, *args, **kwds):
        item = get_object_or_404(cls, *args, **kwds)
        if not item.user_can_manage_me(user):
            raise CannotManage
        return item

Then, in the view functions, this can be used:

def view_func(request, item_id):
    item = YourModelWithOwnership.get_manageable_object_or_404(request.user, id=item_id)
    ...

This will of course raise an exception when the user isn’t the owner and does not have the proper permission. That exception can be handled in the process_exception() method of a custom middleware class so that there’s a single handler for all instances where a user is not allowed to mess with the object.

👤Steef

2👍

A while back I wrote up the usual technique for doing this in the admin. You may want to read through that to see how the implementation works.

0👍

You can look into RowLevelPermissions branch. It hasn’t been included even in 1.1 beta though, I guess it still needs some development.

Leave a comment