Как преобразовать Django HttpResponse в вызов рендеринга Django - PullRequest
7 голосов
/ 30 ноября 2011

У меня есть следующий код

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 выше.

Спасибо

Ответы [ 2 ]

7 голосов
/ 30 ноября 2011

Чтобы ваш оригинальный код работал, вам нужно получить объект RequestContext и передать его вместе с вашим ответом, что-то вроде этого:

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

Прочитайте документацию CSRF поскольку вы можете столкнуться со странными ошибками, если вы не понимаете все способы, которыми CSRF "подключен" в вашем приложении.На странице также есть фрагмент JavaScript, чтобы убедиться, что файлы cookie CSRF отправляются с вашими запросами ajax, если вы отправляете их без формы.

Вы также можете использовать ярлык render_to_response () , новам нужно иметь реальный шаблон для загрузки (в вашем случае вам не нужен шаблон, поэтому в моем примере это «фиктивный» шаблон).

7 голосов
/ 30 ноября 2011

Хорошо, я собираюсь перепроектировать этот ответ, чтобы вы поняли, откуда я.Промежуточное программное обеспечение 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 (не очень хорошо), либо использовать один из доступных вам методов ajax .Если требуемый токен передан в ваше представление, оно будет фактически выполнено.

Причина, по которой ваше представление не вызывается, состоит в том, чтобы предотвратить фактическое действие действия с поддельного сайта - например, если вы отклонили шаблонво время ответа пользователь уже будет зарегестрирован. То же самое происходит с декораторами функций.

Что касается промежуточного программного обеспечения, устанавливающего 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_response и render являются ярлыками для этого, которые делают это:

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