Сообщения Django не работают:

#ajax #django #jquery

#ajax #django #jquery

Вопрос:

Я использую Django 1.2.3 для разработки сайта. Мои запросы ajax get работают нормально, но запросы post работают в режиме разработки (127.0.0.1: 8000), но не тогда, когда я запускаю сайт в рабочую среду с использованием apache nginx.

Вот пример

urls.py:

 (r'api/newdoc/$', 'mysite.documents.views.newdoc'),
  

views.py

 def newdoc(request):
    # only process POST request
    if request.is_ajax():
        data= dict(request.POST)

                # save data to db



    return HttpResponse(simplejson.dumps([True]))
  

в javascript:

 $.post("/api/newdoc/", {data : mydata}, function(data) { alert(data);}, "json");
  

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

что я делаю не так?

Обновления:

решение: токены crsf необходимо отправлять в запросы ajax post (а не получать) начиная с django 1.3

кроме того, согласно приведенной ниже ссылке, следующий javascript

 $.ajaxSetup({
        beforeSend: function(xhr, settings) {
            if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
                // Only send the token to relative URLs i.e. locally.
                xhr.setRequestHeader("X-CSRFToken",
                                     $("#csrfmiddlewaretoken").val());
            }
        }
    });
  

необходимо изменить следующим образом:

 $.ajaxSetup({
        beforeSend: function(xhr, settings) {
            if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
                // Only send the token to relative URLs i.e. locally.
                xhr.setRequestHeader("X-CSRFToken",
                                     $('input[name="csrfmiddlewaretoken"]').val());
            }
        }
    });
  

способ отображения токена csrf в форме, должно быть, изменился в диапазоне 1.25 — 1.3??
несмотря на это, это работает. всем спасибо за вашу помощь

Комментарии:

1. Используйте firebug или webkit’s inspector, чтобы посмотреть, что происходит с запросом, бьюсь об заклад, там ошибка 500.

2. на самом деле я получаю 403 запрещенных

3. … зарегистрировался ли пользователь, который пытается отправить эту форму ajax?

4. у меня пока нет никакой системы аутентификации пользователя

Ответ №1:

Можете ли вы напрямую получить доступ к своим файлам javascript с производственного сервера? Какую версию Django вы используете в рабочей среде? Если вы используете 1.2.5 в рабочей среде, вам нужно будет отправить токен csrf на сервер во время операции публикации AJAX.

Смотрите примечания к выпуску в 1.2.5 и CSRF

Чтобы проверить вашу версию Django:

 import django
django.get_version()
  

Распечатайте приведенное выше на вашем производственном сайте или из оболочки вашего производственного сервера, убедившись, что вы используете правильный путь Python.

Комментарии:

1. $ python -c «импортируйте django; распечатайте django.get_version()» 1.3

2. итак, решение фактически заключалось в том, что токен CSRF не отправлялся с запросом ajax. одно изменение, которое мне пришлось внести, было следующим (взято по ссылке, приведенной в примечаниях к выпуску 1.2.5

3. Похоже, вы используете 1.3 в рабочей среде. Создайте новый virtualenv на своем компьютере разработчика и установите django 1.3. Запустите свой проект оттуда и протестируйте работу post ajax. Возможно, вам потребуется прочитать больше по ссылке CSRF, которую я разместил выше.

Ответ №2:

При беглом взгляде ваш код выглядит нормально, но я покажу вам пример моего кода обработки форм ajax в надежде, что это поможет разобраться в возникшей ошибке. Хотя то, что прокомментировал @dmitry, должно быть вашим первым шагом отладки — используйте firebug или инспектор, чтобы увидеть, возвращает ли вызов ajax ошибку.

 // js (jQuery 1.5)
$(form).submit(function(event) {
            event.preventDefault();
            $.post(post_url, $(form).serialize())
              .success(function(data, status, jqxhr) {
                if (data.success) { // form was valid
                    $(form)
                    // other irrelevant code
                    .siblings('span')
                      .removeClass('error')
                      .html('Form Successful');
                } else { // form was invalid
                    $(form).siblings('span').addClass('error').html('Error Occurred');
                }
              })
              .error(function(jqxhr, status, error) { // server error
                $(form).siblings('span').addClass('error').html("Error: "   error);
              });
});


// django
class AjaxFormView(FormView):
    def ajax_response(self, context, success=True):
        html = render_to_string(self.template_name, context)
        response = simplejson.dumps({'success': success, 'html': html})
        return HttpResponse(response, content_type="application/json", mimetype='application/json')


// view deriving from AjaxFormView

    def form_valid(self, form):
        registration = form.save()
        if self.request.is_ajax():
            context = {'competition': registration.competition }
            return self.ajax_response(context, success=True)
        return HttpResponseRedirect(registration.competition.get_absolute_url())

    def form_invalid(self, form):
        if self.request.is_ajax():
            context = { 'errors': 'Error Occurred'}
            return self.ajax_response(context, success=False)
        return render_to_response(self.template_name, {'errors':form.errors})
  

На самом деле, сравнивая приведенное выше с вашим кодом, вам, возможно, потребуется установить content_type в вашем представлении django, чтобы jQuery мог понять и обработать ответ. Обратите внимание, что в приведенном выше примере используются представления на основе классов django 1.3, но логика должна быть знакома независимо от этого. Я использую context.success для сигнализации о том, прошла ли обработка формы или произошел сбой — поскольку действительный ответ (json) любого вида будет сигнализировать о том, jQuery.post что запрос был успешным.

Комментарии:

1. добавлено content_type=»application / json», mimetype = ‘application / json’ в мой HttResponse, хотя без кубиков