How to convert a Django HttpResponse to a Django render call

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-03 14:51:36

To make your original code work, you need to get a RequestContext object and pass it along with your response, something like this:

from django.http import HttpResponse
from django.template import RequestContext, Template

def ajax_login_request(request):
   # ...

   # This bit of code adds the CSRF bits to your request.
   c = RequestContext(request,{'result':json.dumps(result)})
   t = Template("{{result}}") # A dummy template
   response = HttpResponse(t.render(c), mimetype = u'application/json')
   return response

Do read up on the CSRF documentation as you might run into strange errors if you don't understand all the ways CSRF is "wired" in your app. The page also has a javascript snippet to make sure CSRF cookies are sent with your ajax requests if you are sending them without a form.

You can also use the render_to_response() shortcut, but you would need to have an actual template to load (in your case, you don't need a template, hence the "dummy" template in my example).

Ok, I'm going to re-draft this answer so you understand where I'm coming from. The CSRF middleware works like this:

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

In other words, if you are seeing a 403 csrf page, your view was never called. You can confirm this by sticking a spurious print statement in the view and watching the output from runserver when you make your request.

To solve this, you either need to disable csrf (not good) or use one of the ajax methods available to you. If the required token is passed in your view will actually be executed.

The reason your view is not called is to prevent the action from the forged site from actually ever taking place - for example, if you denied the template at response time the user would already be logged in. The same behaviour occurs with the function decorators.

As for the middleware setting the cookie, that does not alter or depend on the render function at all - this sets the HTTP header Cookie: ... in the response. All responses in Django are HttpResponse objects until it finally converts them to output; render functions are helpers, but that's not what's causing your problem here.

Edit I'll convert what you've got to a render call. You could do this:

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

Where ajax_templates/login_response.html is just:

{% loginresponse %}

That's it. HttpResponse has a main default argument which is the string to return (literally, the html of the web page); that's what you're doing initially. render_to_response and render are shortcuts to this which do this:

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!