Object Ownership in Django

后端 未结 3 2101
没有蜡笔的小新
没有蜡笔的小新 2021-01-31 12:22

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

相关标签:
3条回答
  • 2021-01-31 12:45

    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 讨论(0)
  • 2021-01-31 12:49

    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.

    0 讨论(0)
  • 2021-01-31 13:00

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

    0 讨论(0)
提交回复
热议问题