Перенаправление после сообщения AJAX в Django

Я использую Django встроенный DeleteView, и я присвоил значение атрибуту success_url. Теперь в моем шаблоне я запускаю это представление с помощью метода JQuery '$.post(). Когда элемент удален, я не перенаправляюсь на success_url. После некоторого поиска я обнаружил, что это проблема с методом AJAX post, который игнорирует перенаправление.

Я исправил это, добавив функцию, чтобы установить window.location="#myRedirectionURL" в качестве третьего параметра $.post() в JQuery.

Однако этот способ кажется не очень Django. По сути, он решает проблему с точки зрения AJAX, а не Django. Что еще, он оставляет success_url в DeleteView бесполезным (но вам все равно нужно назначить значение success_url, или Django вызовет ошибку).

Итак, это правильный способ перенаправления при отправке через AJAX? Есть ли лучший способ сделать это?

Большое спасибо.

Ответ 1

Ajax не будет перенаправлять страницы!

То, что вы получаете от перенаправления, это html-код с новой страницы внутри объекта данных в ответ POST.

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

На сервере

Если у вас есть ошибка

response = {'status': 0, 'message': _("Your error")} 

Если все прошло нормально

response = {'status': 1, 'message': _("Ok")} # for ok

Отправить ответ:

return HttpResponse(json.dumps(response), content_type='application/json')

на странице html:

$.post( "{% url 'your_url' %}", 
         { csrfmiddlewaretoken: '{{ csrf_token}}' , 
           other_params: JSON.stringify(whatever)
         },  
         function(data) {
             if(data.status == 1){ // meaning that everyhting went ok
                // do something
             }
             else{
                alert(data.message)
                // do your redirect
                window.location('your_url')
             }
        });

Если вы не знаете, куда отправить пользователя, и вы предпочитаете получать этот URL-адрес с сервера, просто отправьте его как параметр:

response = {'status': 0, 'message': _("Your error"), 'url':'your_url'} 

затем замените это на расположение окна:

 alert(data.message)
 // do your redirect
 window.location(data.url)

Ответ 2

http://hunterford.me/how-to-handle-http-redirects-with-jquery-and-django/

этот работает для меня, возможно, выглядит как хак

django middleware

from django.http import HttpResponseRedirect

class AjaxRedirect(object):
    def process_response(self, request, response):
        if request.is_ajax():
            if type(response) == HttpResponseRedirect:
                response.status_code = 278
        return response

Javascript

$(document).ready(function() {
    $(document).ajaxComplete(function(e, xhr, settings) {
        if (xhr.status == 278) {
            window.location.href = xhr.getResponseHeader("Location");
        }
    });
});

Ответ 3

Может быть, вы можете попробовать переопределить метод delete() в DeleteView и использовать HttpResponseRedirect? Я использовал это для выполнения нескольких удалений в одной транзакции, когда у меня была такая же проблема с игнорированием функции get_success_url. (Следующий код не проверен - просто идея действовать как отправная точка)

class DeleteRecord(views.DeleteView) :
    model = models.Record

    def delete(self, request, *args, **kwargs) :
        super(DeleteRecord, self).delete(*args, **kwargs)
        url = "http://whatever.your.url.is"
        return HttpResponseRedirect(url)

Ответ 4

django-ajax ajaxPost позволяет перенаправлять, если вы передаете ему обычный URL-адрес (как ответ json). В моем случае методы JQuery ajax() не работали.