2013-01-31 43 views
1

我在我们的代码中做一些重构。一个@render_to_json装饰者在内部调用is_logged_in方法。我正在删除它,只是简单地添加另一个明确的@login_required装饰器。Python/Django装饰器可以访问哪些信息?

问题是我们的某些方法是通过AJAX调用的,并期望他们接着采取行动的json响应为{"status": "logged_out"}。所以我需要改变我们的login_required方法来以某种方式检查两件事之一。

  • 了这方法通过AJAX调用,也许检测XMLHttpRequest
  • render_to_json装饰也要求这一请求。我们的想法是,如果login_required方法知道请求期待json,那么它可能会返回json数据包,否则正常情况下会重定向。

UPDATE添加第3个选项。

  • 在每种情况下与所述@render_to_json装饰的方法,所述@login_required装饰器之前它被引用。如果用户注销,@login_required方法将返回HttpResponseRedirect。在@render_to_json方法中,我将如何检查login_required方法的返回类型并进行适当的响应?

想法?问题?

我应该加我也是相当新的Python,所以我可能会缺少一些基本的东西。如果是这样,帮我学习?

UPDATE

我要继续前进,在这里添加两个修饰以供参考。

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 
+1

装饰者可以访问它正在装饰的函数所调用的所有参数,所以我不确定我是否理解了第一个要点。 –

+0

David。请记住,我是一般的Python新手。我怀疑是这样,但不确定。根据这篇文章,我会使用请求。META获得对所有请求头的访问权限? http://stackoverflow.com/questions/3889769/get-all-request-headers-in-django – commadelimited

+0

我会特别寻找这个请求标题 'X-Requested-With XMLHttpRequest' – commadelimited

回答

1

装饰可以访问所有的数据“Decoratee”正在接收:

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现在知道该怎么做。

你也可以使用这种相同的方法将装饰器中的数据冒泡到装饰器中。

+0

谢谢。非常彻底的回应...感谢你的时间。 – commadelimited

相关问题