我在代码中做了一些重构。@render_to_json
装饰器在内部调用is_logged_in
方法。我删除它是为了简单地添加另一个显式@login_required
装饰器。
问题是我们的一些方法是通过 AJAX 调用的,并且期望 json 响应{"status": "logged_out"}
然后它们采取行动。所以我需要更改我们的login_required方法,以某种方式检查两件事之一。
- 此方法是否通过 AJAX 调用,可能检测到
XMLHttpRequest
标头 - 是
render_to_json
装饰者也要求这个请求。想法是,如果login_required
方法知道请求需要 json,那么它可以返回 json 数据包,否则正常重定向。
更新 添加第三个选项。
- 在每种情况下,使用
@render_to_json
修饰器的方法,@login_required
装饰器都会在其之前引用。如果用户注销,@login_required
方法将返回HttpResponseRedirect
。在@render_to_json
方法中,我将如何检查login_required方法的返回类型并做出适当的响应?
思潮?问题?
我应该补充一点,我对Python也很陌生,所以我可能缺少一些基本的东西。如果是这样,请帮我学习?
更新
我将继续在此处添加两个装饰器以供参考。
def render_to_json(fn):
@wraps(fn)
def inner(request, *args, **kwargs):
result = fn(request, *args, **kwargs)
return HttpResponse(json.dumps(result), mimetype='application/json')
return inner
def login_required(func):
@wraps(func)
def _decorator(request, *args, **kwargs):
if not is_logged_in(request):
from apps.core.extendedLogging import ExtendedLogging
ExtendedLogging.log("In login req'd: it appears that the user is not logged in", request)
request.session['login_referrer_uri'] = request.build_absolute_uri()
return HttpResponseRedirect(settings.LOGIN_URL)
return func(request, *args, **kwargs)
return _decorator
装饰者可以访问"装饰者"接收的所有数据:
def method_decorator(operation):
"""
On this case operation = view_method
"""
def wrapper(*args, **kwargs):
"""
Receives all arguments the requested operation would receive
"""
request = args[0]
param = args[1]
more_param = args[2]
return operation(request, param, more_param)
return wrapper
@method_decorator
def view_method(request, param, more_param):
#something
所以,当你打电话给"view_method"时,首先你会抛出"method_decorator",然后叫"view_method"。
现在,在装饰器中,您可以验证所需的任何内容并传递新信息,例如:
def wrapper(*args, **kwargs):
...
if some_condition:
request.new_content = new_content
return operation(request, param, more_param)
return wrapper
这将允许您在请求的view_method上接收new_content:
@method_decorator
def view_method(request, param, more_param):
new_content = request.new_content
而且,希望view_method现在知道该怎么做。
您还可以使用相同的方法将数据从一个装饰器冒泡到另一个装饰器。