Джанго комментирует - неудача Ajax и CSRF - PullRequest
0 голосов
/ 05 июля 2011

Я думаю, что это отличается от других проблем здесь, я проверил ответы и до сих пор не повезло.Спасибо за любую помощь:

У меня есть список новостных элементов (например, лента фейсбука), и к каждому из них прикреплена форма комментария (с помощью приложения django.contrib.comments).Нормально работает.

НО, я использую своего рода «бесконечную прокрутку» AJAX на странице - при прокрутке она загружает следующий набор новостных элементов и соответствующую форму комментариев через AJAX.Формы комментариев к только что загруженным новостным элементам не работают (происходит сбой при проверке CSRF).

Очевидно, почему - {% csrf_token%} не передается ответу JSON, который возвращается,поэтому у недавно загруженных форм комментариев нет данных CSRF.

Я пытался использовать метод set cookie на страницах Django (https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/#ajax),, но, похоже, не работает и не пытается использовать декоратор @csrf_exemptчтобы полностью исключить CSRF.

Любые предложения, как я могу передать csrf_token вместе с возвращаемым ответом JSON? Или есть альтернатива?

Вот мнение:

def my_view(request):
    # the normal view gets a queryset of all Info items and returns them
    infos = Info.objects.all()
    ....

    # here's the AJAX part
    if request.GET.get('xhr') and page > 1:
        infos = paginator.page(int(request.GET.get('page')))
        objects_list = []
        for object in infos:
            objects_list.append(render_to_string('list/snippets/feed_li.html', {
                'object': object,
            }))

        json =  simplejson.dumps(objects_list, cls=DjangoJSONEncoder)
        return HttpResponse(json, mimetype='application/json')

Ответы [ 2 ]

0 голосов
/ 19 января 2012

Сначала проверьте, если вы забыли включить {% csrf_token%} в 'list / snippets / feed_li.html';

Во-вторых, чтобы правильно функционировать токен csrf, вы должны использовать RequestContext или вручнуюсгенерируйте токен и добавьте его в контекстную переменную при рендеринге шаблона (см. Django csrf ref ).Таким образом, замените строку:

objects_list.append(render_to_string('list/snippets/feed_li.html', {
    'object': object,
}))

на:

''' from django.template import RequestContext ''' 
objects_list.append(render_to_string('list/snippets/feed_li.html', \
    RequestContext(request, {'object':object})
))

или:

''' from django.core.context_processors import csrf '''
vars = {}
vars.update(csrf(request))
vars.update({'object':object})
objects_list.append(render_to_string('list/snippets/feed_li.html', vars))
0 голосов
/ 05 июля 2011

Одним из вариантов будет предоставление токена CSRF для вашей формы через ответ JSON, который вы возвращаете. Я полагаю, что вы можете получить токен CSRF программно, позвонив по номеру django.middleware.csrf.get_token(request), а затем включив это значение в ваш ответ ajax.

Другой вариант, о котором я могу подумать, - отключить защиту CSRF для этого представления.

...