我该如何为我的Django/Python视图编写装饰器?

4 投票
3 回答
5310 浏览
提问于 2025-04-16 07:51

这是我的看法。基本上,它会根据用户是否登录来返回不同的响应。

@check_login()
def home(request):
    if is_logged_in(request): 
        return x
    else:
        return y

这是我的装饰器代码。我只是想检查请求是否有头信息,如果有的话,就让他登录。

#decorator to log the user in if there are headers
def check_login():
    def check_dec(func):
        if request.META['username'] == "blah":
            login(request, user)

    return check_dec

问题是……我不知道在这种情况下怎么写一个合适的装饰器!!!参数是什么?函数是什么?怎么做?

3 个回答

2

这是我写的一个装饰器,用来检查用户是否在某个特定的组里。它的功能稍微多一点。

https://github.com/mzupan/django-decorators/blob/master/auth.py

你可以这样使用它:

@group_required(["group1", "group2"])
def show_index(request):
    view_code_here

如果用户在group1或group2其中一个组里就可以,如果不在的话,就会看到404页面。

4

一个普通的装饰器就是一个函数,它接受一个函数或类,然后返回其他东西(通常是同样类型的,但这并不是必须的)。而一个带参数的装饰器是一个返回装饰器的函数。

所以,考虑到这一点,我们创建一个闭包并返回它:

def check_login(func):
  def inner(request, *args, **kwargs):
    if request.META['username'] == 'blah':
      login(request, user) # I have no idea where user comes from
    func(request, *args, **kwargs)
  return inner
12

只用 @check_login,不要用 check_login(),否则你的装饰器就得返回一个装饰过的函数,就像你在 home = check_login()(home) 里做的那样。

这里有一个装饰器的例子:

def check_login(method):
    @functools.wraps(method)
    def wrapper(request, *args, **kwargs):
        if request.META['username'] == "blah"
            login(request, user) # where does user come from?!
        return method(request, *args, **kwargs)
    return wrapper

这个装饰器会在用户名字段设置为“blah”的时候执行你的登录函数,然后再调用原来的方法。

撰写回答