Как отправить POST в форму django с помощью AJAX & jQuery
Я проверил множество учебных руководств для форм AJAX для Django, но каждый из них говорит вам об одном способе этого, ни один из них не является простым, и я немного смущен, так как я никогда не работал с AJAX.
У меня есть модель под названием "note", модель для нее, и внутри шаблона мне нужно, чтобы каждый раз, когда элемент примечания посылает сигнал stop() (из jQuery Sortables), django обновляет объект.
Мой текущий код:
views.py
def save_note(request, space_name):
"""
Saves the note content and position within the table.
"""
place = get_object_or_404(Space, url=space_name)
note_form = NoteForm(request.POST or None)
if request.method == "POST" and request.is_ajax:
msg = "The operation has been received correctly."
print request.POST
else:
msg = "GET petitions are not allowed for this view."
return HttpResponse(msg)
JavaScript:
function saveNote(noteObj) {
/*
saveNote(noteObj) - Saves the notes making an AJAX call to django. This
function is meant to be used with a Sortable 'stop' event.
Arguments: noteObj, note object.
*/
var noteID = noteObj.attr('id');
$.post("../save_note/", {
noteid: noteID,
phase: "Example phase",
parent: $('#' + noteID).parent('td').attr('id'),
title: $('#' + noteID + ' textarea').val(),
message: "Blablbla",
});
}
Текущий код получает данные из шаблона и печатает его в терминале. Я не знаю, как я могу манипулировать этими данными. Я видел, как некоторые люди управляют данными через jqueryforms для отправки данных в django.
Как я могу получить доступ к данным, отправленным AJAX и обновить объект примечания?
Ответы
Ответ 1
Поскольку вы используете jQuery, почему бы не использовать следующее:
<script language="JavaScript">
$(document).ready(function() {
$('#YOUR_FORM').submit(function() { // catch the form submit event
$.ajax({ // create an AJAX call...
data: $(this).serialize(), // get the form data
type: $(this).attr('method'), // GET or POST
url: $(this).attr('action'), // the file to call
success: function(response) { // on success..
$('#DIV_CONTAINING_FORM').html(response); // update the DIV
}
});
return false;
});
});
</script>
РЕДАКТИРОВАТЬ
Как указано в комментариях, иногда выше не будет работать. Поэтому попробуйте следующее:
<script type="text/javascript">
var frm = $('#FORM-ID');
frm.submit(function () {
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
success: function (data) {
$("#SOME-DIV").html(data);
},
error: function(data) {
$("#MESSAGE-DIV").html("Something went wrong!");
}
});
return false;
});
</script>
Ответ 2
Вы можете получить доступ к данным запроса POST, используя имя переменной, в вашем случае:
request.POST["noteid"]
request.POST["phase"]
request.POST["parent"]
... etc
Объект request.POST не может быть включен. Вы должны назначить значение переменной, а затем манипулировать ею.
Я бы посоветовал использовать этот плагин JQuery, чтобы вы могли писать обычные HTML-формы, а затем получать их "обновлен" до AJAX. Наличие $.post везде в вашем коде довольно утомительно.
Кроме того, используйте представление Network on Firebug (для Firefox) или инструменты разработчика для Google Chrome, чтобы вы могли просматривать, что посылается вам AJAX-вызовами.
Ответ 3
Что-то, на что нужно обратить внимание, - это вернуть форму как html, отрезанный до модального.
Views.py
@require_http_methods(["POST"])
def login(request):
form = BasicLogInForm(request.POST)
if form.is_valid():
print "ITS VALID GO SOMEWHERE"
pass
return render(request, 'assess-beta/login-beta.html', {'loginform':form})
Простой вид, чтобы вернуть html snipped
Форма html Snipped
<form class="login-form" action="/login_ajx" method="Post">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="header">Authenticate</h4>
</div>
<div class="modal-body">
{%if form.non_field_errors %}<div class="alert alert-danger">{{ form.non_field_errors }}</div>{%endif%}
<div class="fieldWrapper form-group has-feedback">
<label class="control-label" for="id_email">Email</label>
<input class="form-control" id="{{ form.email.id_for_label }}" type="text" name="{{ form.email.html_name }}" value="{%if form.email.value %}{{ form.email.value }}{%endif%}">
{%if form.email.errors %}<div class="alert alert-danger">{{ form.email.errors }}</div>{%endif%}
</div>
<div class="fieldWrapper form-group has-feedback">
<label class="control-label" for="id_password">Password</label>
<input class="form-control" id="{{ form.password.id_for_label }}" type="password" name="{{ form.password.html_name}}" value="{%if form.password.value %}{{ form.password.value }}{%endif%}">
{%if form.password.errors %}<div class="alert alert-danger">{{ form.password.errors }}</div>{%endif%}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<input type="submit" value="Sign in" class="btn btn-primary pull-right"/>
</div>
</form>
Страница, содержащая модальный
<div class="modal fade" id="LoginModal" tabindex="-1" role="dialog">{% include "assess-beta/login-beta.html" %}</div>
Используйте тег include, чтобы загрузить загруженную на страницу загрузку, поэтому она доступна при открытии модального файла.
Modal.js
$(document).on('submit', '.login-form', function(){
$.ajax({
type: $(this).attr('method'),
url: this.action,
data: $(this).serialize(),
context: this,
success: function(data, status) {
$('#LoginModal').html(data);
}
});
return false;
});
Использование .on() в этом случае работает как .live(), который связывает событие отправки не с кнопкой, а с документом.
Ответ 4
Как и другие ответы, я предпочитаю использовать jQuery Form Plugin. Он полностью поддерживает то, что вы хотите, и многое другое. Представление post обрабатывается, как обычно, в части Django, просто возвращая заменяемый HTML.
Ответ 5
На стороне сервера ваш код django может обрабатывать пост AJAX так же, как он обрабатывает другие формы. Например,
views.py
def save_note(request, space_name):
"""
Saves the note content and position within the table.
"""
place = get_object_or_404(Space, url=space_name)
note_form = NoteForm(request.POST or None)
if request.method == "POST" and request.is_ajax():
print request.POST
if note_form.is_valid():
note_form.save()
msg="AJAX submission saved"
else:
msg="AJAX post invalid"
else:
msg = "GET petitions are not allowed for this view."
return HttpResponse(msg)
Я предположил, что ваш NoteForm - это ModelForm - он должен быть - поэтому у него есть метод сохранения. Обратите внимание, что в дополнение к добавлению команды save()
я изменил ваш request.is_ajax
на request.is_ajax()
, который вы хотите (если вы используете request.is_ajax
, ваш код будет просто проверять, имеет ли запрос метод под названием is_ajax
, что, очевидно, и есть).
Ответ 6
Большинство примеров использования AJAX POST с формами Django, включая официальный пример:
https://docs.djangoproject.com/en/1.9/topics/class-based-views/generic-editing/#ajax-example
являются точными, если ModelForm.clean()
не вызвало ошибок (form_valid
).
Однако они не выполняют сложную задачу: перевод ошибок ModelForm
с помощью ответа AJAX на клиентскую сторону Javascript/DOM.
Мое подключаемое приложение использует маршрутизацию ответа AJAX с режимами просмотра на стороне клиента, чтобы автоматически отображать ошибки проверки AJAX post ModelForm
на основе классов, аналогичные тем, как они будут отображаться в традиционном HTTP POST:
https://django-jinja-knockout.readthedocs.org/en/latest/forms.html#ajax-forms-processing
https://django-jinja-knockout.readthedocs.org/en/latest/viewmodels.html
Поддерживаются оба шаблона Jinja2 и Django.