【问题标题】:Possible to use decorators in django to do permissions based on a view parameter?可以在 django 中使用装饰器根据视图参数执行权限吗?
【发布时间】:2014-01-21 00:03:18
【问题描述】:

我不确定这是否可能,但有没有办法写出类似的东西

@group_required('group_id')
def myview(request, group_id):
    .....

我在哪里查看参数 group_id 的值并将此视图的访问权限仅限于该组中的人?

我知道可以创建一个装饰器来检查某个特定组的成员身份

@group_required('admin')
def myview(request):
   ....

但是假设我想要一个只有特定组内的人才能访问的视图,这由 url 决定。

例如

/group/1
/group/2

每个人都应该拥有权限,以便只有组#X 的成员才能看到该页面。我可以在视图中轻松编写此功能

group = get group
if user not in group
    raise 404

但这种逻辑一直在重复。装饰器似乎是一种很有前途的方法,但似乎范围倒退了。是否有另一种首选方式来处理此类权限?

谢谢!

【问题讨论】:

  • 如果您使用的是 CBV,请检查 django-braces:django-braces.readthedocs.org/en/latest/index.html
  • 我们项目的一部分使用了 CBV,但我想知道在基于函数的视图上是否可行。我也不太清楚如何使用 CBV 完成此操作,但我会再看看
  • 看起来好像基于组的权限限制了基于 specific 组的访问——而不是组是通过视图 url 参数进入的变量
  • 有自定义组要求示例:django-braces.readthedocs.org/en/latest/…

标签: django permissions decorator


【解决方案1】:

装饰器可以访问所有视图参数,所以这绝对是可能的。你可以这样做:

def group_required(arg_name):
    def decorator(view):
        def wrapper(request, *args, **kwargs):
            group_id = kwargs.get(arg_name)
            user = request.user
            if group_id in user.groups.values_list('id', flat=True):
                return view(request, *args, **kwargs)
            else:
                return HttpResponseForbidden # 403 Forbidden is better than 404
        return wrapper
    return decorator

(如果你不需要在装饰器中动态定义参数的灵活性,例如,如果你总是调用它group_id,你可以在这里忽略外部函数而直接使用kwargs.get('group_id')。)

【讨论】:

  • 非常感谢!这加上重读这个问题stackoverflow.com/a/1594484/216877 帮助我弄清楚了。为什么在这里说 403 比 404 好?
  • 因为 404 表示 Not Found,这里不是这样:资源找到了,但是用户没有权限。禁止更合适。
【解决方案2】:

丹尼尔的回答似乎不适用于 Django 1.11。这是修改后的版本:

def group_required(group_name):
    def decorator(view):
        @functools.wraps(view)
        def wrapper(request, *args, **kwargs):
            if (request.user.groups.filter(name=group_name).exists() or
                    request.user.is_superuser):
                return view(request, *args, **kwargs)
            else:
                return HttpResponseForbidden("You don't have permission to view this page.")
        return wrapper
    return decorator

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-25
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 2012-02-01
    • 2015-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多