【问题标题】:Object Ownership in DjangoDjango 中的对象所有权
【发布时间】:2009-06-16 00:09:49
【问题描述】:

我想知道如何使用 django 模型完成一个简单的“对象所有权”系统,这样,默认情况下,只有对象的所有者可以编辑它。

我正在尝试允许“管理”组代表对象所有者编辑所有对象,并且此时添加了自定义权限:

class Meta:
    permissions     = (
        ("manage_object", "Can manage objects"),
    )

为了建立“所有权”,我想出了在模型中添加 def 的想法:

def owner(self):
    return self.user

但是,我该如何走得更远?我可以在视图中实现权限并使用模板显示相关的 UI,即:

if request.user is object.owner:
    # ... do stuff
elseif request.user.has_perm.can_manage:  # this line is probably not right
    # ... do something else

...然后在模板级别呈现不同的 UI 元素。

所以,问题是:

  • 这种方法有什么缺点/好处?
  • 有建议吗?
  • 或者,任何其他以前实现的方法?

非常感谢!

【问题讨论】:

    标签: django


    【解决方案1】:

    我的方法是在模型中添加一个方法:

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

    然后,每当需要进行权限检查时,我都会调用该方法,并根据结果采取一些措施。所以对于这样的观点

    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:
            ...
    

    后来我可能会意识到,在每个需要测试的视图中编写的样板代码仍然相当多,所以我会实现一个当用户无法管理对象时抛出的异常......

    class CannotManage(Exception):
        pass
    

    ...并向模型添加另一个方法:

    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
    

    然后,在视图函数中,可以使用:

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

    当用户不是所有者并且没有适当的权限时,这当然会引发异常。该异常可以在custom middleware 类的process_exception() 方法中处理,因此对于不允许用户弄乱对象的所有实例都有一个处理程序。

    【讨论】:

    • 是的,但是如果您只想要一个阻止访问更新/删除视图的视图装饰器呢?
    【解决方案2】:

    不久前我写了the usual technique for doing this in the admin。您可能需要通读它以了解实现的工作原理。

    【讨论】:

      【解决方案3】:

      您可以查看RowLevelPermissions 分支。虽然它甚至没有包含在 1.1 beta 中,但我想它仍然需要一些开发。

      【讨论】:

      • 那个分支完全,完全,100% 永远死了。它永远不会复活、完成、更新或集成到主线 Django。不幸的是,SVN 没有任何方式说“这个分支已经关闭,将没有进一步的工作”,所以人们一直在绊倒它。
      猜你喜欢
      • 2023-03-16
      • 1970-01-01
      • 2018-06-25
      • 1970-01-01
      • 1970-01-01
      • 2019-12-24
      • 2017-07-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多