Object Ownership in Django

后端 未结 3 2146
没有蜡笔的小新
没有蜡笔的小新 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条回答
  •  猫巷女王i
    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.

提交回复
热议问题