如何将Django HttpResponse转换为Django渲染调用

时间:2011-11-30 14:09:25

标签: django httpresponse csrf

我有以下代码

def ajax_login_request(request):
   try:
      request.POST[u'login']
      dictionary = request.POST
   except:
      dictionary = request.GET
   user = authenticate(username = dictionary[u'login'], password = dictionary[u'password'])
   if user and user.is_active:
      login(request, user)
      result = True
   else:
      result = False
   response = HttpResponse(json.dumps(result), mimetype = u'application/json')
   return response

通过ajax调用。我是一个菜鸟,这是一本书中的例子。不幸的是,我正在使用的Django版本会引发CSRF错误。我已经完成了其他CSRF位,但我不知道如何将HttpResponse位更改为渲染调用。我不想使用CSRF_exempt,因为我不知道什么时候合适。有人可以为我提供上面HttpResponse的等效渲染调用。

由于

1 个答案:

答案 0 :(得分:7)

好的,我将重新起草这个答案,以便你了解我的来源。 CSRF中间件的工作方式如下:

You make request   -------> request hits csrf --(invalid/no token)--> render 403 
                             middleware      
                                   |
                             (valid token)
                                   |
                                  \ /
                             Call view 
                                   |
                                  \ /
                            middleware sets 
                            csrf cookie
                                   |
                                  \ /
                            Response appears

换句话说,如果您看到403 csrf页面,则从未调用过您的视图。您可以通过在视图中粘贴虚假的打印语句并在发出请求时观察runserver的输出来确认这一点。

要解决此问题,您需要禁用csrf(不好)或使用one of the ajax methods available to you。如果在视图中传递了所需的标记,则实际上将执行。

未调用视图的原因是为了防止伪造网站的操作实际发生 - 例如,如果您在响应时拒绝了模板,则用户已经登录。同样的行为发生在函数装饰器。

对于设置cookie的中间件,它根本不会改变或依赖于渲染功能 - 这会在响应中设置HTTP头Cookie: ...。 Django中的所有响应都是HttpResponse个对象,直到它最终将它们转换为输出; render函数是帮助程序,但这不是导致问题的原因。

编辑我会将您所拥有的内容转换为渲染调用。你可以这样做:

return render_to_response(`ajax_templates/login_response.html`, 
                          {'loginresponse': json.dumps(result)})

ajax_templates/login_response.html只是:

{% loginresponse %}

就是这样。 HttpResponse有一个主要的默认参数,它是要返回的字符串(字面意思是网页的html);这就是你最初做的事情。 render_to_responserender是执行此操作的快捷方式:

render_to_response called ----> open template asked for --> substitute arguments 
                                                                      |
                                                                     \ /
django instructs web server   <--- return this from view <-- create HttpResponse 
      to send to client                                          object