I\'m wondering how I might accomplish a simple \'object ownership\' system with django models, such that, by default, only the owner of an object may edit it.
I am attem
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.
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.
You can look into RowLevelPermissions branch. It hasn't been included even in 1.1 beta though, I guess it still needs some development.