Search code examples
djangohttpresponsecsrf

How to convert a Django HttpResponse to a Django render call


I have the following code

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

which is being called via ajax. I'm a noob and this is from an example in a book. Unfortunately the version of Django I'm using throws a CSRF error on this. I've done the other CSRF bits, but I don't know how to change the HttpResponse bit to a render call. I do not want to use CSRF_exempt, because I have no idea when that is appropriate. Can someone please provide me the equivalent render call for the HttpResponse above.

Thanks


Solution

  • 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).