Простой способ отправки форм Django с использованием Ajax jQuery
Я относительно новичок в Ajax, и я все еще пытаюсь понять все концепции. Я попытался заглянуть в кучу учебников для представления формы Ajax-Django, для большинства из них требуются формы jQuery, которые не кажутся легким способом обработки формы для меня. Мне трудно понять концепцию.
Я пытаюсь написать некоторые формы формы на основе ajax для регистрации пользователей, входа в систему, создания сообщений и комментариев. И пока я не нашел способ, который облегчает мне понимание того, как будет работать подход Ajax.
Я бы очень признателен за любую помощь, которую я могу получить в этом отношении.
Это то, что я пробовал до сих пор.
change_pw.html
{% extends "base.html" %}
{% block title %}Change Password{% endblock %}
{% block head %}Change Password{% endblock %}
{% block content %}
{% include "modal_change_pw.html" %}
{% endblock %}
modal_change_pw.html
<div id="modalchangepw">
<ul style="margin:5px;">
<ul class="thumbnails" style="margin: 0 auto;background: white;">
<div class="thumbnail row-fluid" style="background: white; padding: 10px;width: 97%; -moz-border-radius: 5px;border-radius: 5px;-moz-box-shadow:3px 3px 5px 0px #ccc;-webkit-box-shadow:3px 3px 5px 0px #ccc;box-shadow:3px 3px 5px 0px #ccc;">
<br>
{% if not error == '' %}
<div class="alert alert-error">
<button type="button" class="close" data-dismiss="alert">×</button>
{{ error }}
</div>
{% endif %}
{% if not success == '' %}
<div class="alert alert-success">
<button type="button" class="close" data-dismiss="alert">×</button>
{{ success }}
</div>
{% endif %}
{% if messages %}
{% for message in messages %}
<div{% if message.tags %} class="alert alert-{{ message.tags }}"{% endif %}>
<button type="button" class="close" data-dismiss="alert">×</button>
{{ message|safe }}
</div>
{% endfor %}
{% endif %}
<form id = 'changepw' enctype="multipart/form-data" method="post" action=".">
<p><label for="id_currentpw">Current Password:</label> <input type="password" name="currentpw" id="id_currentpw" /></p>
<p><label for="id_newpw1">New Password:</label> <input type="password" name="newpw1" id="id_newpw1" /></p>
<p><label for="id_newpw2">Re-enter New Password:</label> <input type="password" name="newpw2" id="id_newpw2" /></p>
<input class="btn btn-primary" type="submit" value="submit"/>
{% csrf_token %}
</form>
</div>
</ul>
</ul>
</div>
views.py
def change_pw(request):
user=request.user
error=''
success=''
if request.method == 'POST':
form = ChangePw(request.POST)
if form.is_valid():
currentpw=form.cleaned_data['currentpw']
newpw1=form.cleaned_data['newpw1']
newpw2=form.cleaned_data['newpw2']
if currentpw and newpw1 and newpw2:
if user.check_password(currentpw):
if newpw1==newpw2:
user.set_password(newpw1)
user.save()
success='Password updated!!'
if request.is_ajax() :
messages.success(request, 'Password updated.')
return HttpResponseRedirect ('/changepw/')
else:
return HttpResponseRedirect ('/user/%s/' % user.username)
else:
error='New passwords do not match'
else:
error='Incorrect Current Password'
else:
error='Enter all Password fields to make any changes'
else:
form = ChangePw()
variables = RequestContext(request, {
'form':form,
'error':error,
'success':success
})
if request.is_ajax() :
return render_to_response('modal_change_pw.html', variables)
else:
return render_to_response('change_pw.html', variables)
forms.py
class ChangePw(forms.Form):
currentpw = forms.CharField(
label=u'Current Password',
required=False,
widget=forms.PasswordInput()
)
newpw1 = forms.CharField(
label=u'New Password',
required=False,
widget=forms.PasswordInput()
)
newpw2 = forms.CharField(
label=u'Re-enter New Password',
required=False,
widget=forms.PasswordInput()
)
JQuery
//Change PW
$('#changepw').live('submit', function(event) { // catch the form submit event
event.preventDefault();
$.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..
$('#modalchangepw').html(response); // update the DIV
}
});
return false;
});
Теперь код работает нормально.
Но моя цель - обрабатывать эти формы модально, так что пользователю не нужно оставлять страницу, на которой он/она сейчас находится. В случае модального всплывающего окна моя форма, кажется, не представляет значения.
Ответы
Ответ 1
Концепция AJAX
не сильно отличается от того, как работают общие формы. Идея AJAX состоит в том, чтобы асинхронно передавать (передавать) данные на сервер.
Как это работает?
При общем представлении формы поток идет примерно так.
User submits a POST request
↓
Server Does the Data Processing
↓
Redirects to a Success or Failure Page
С ajax он работает довольно похоже.
User Submits a form through AJAX
↓
AJAX sends the POST data to the server in the background and waits for a response
↓
Server does the Data Processing
↓
and sends a Response back to AJAX
↓
AJAX sends the response back to the same template where the request was initiated.
Теперь давайте посмотрим на простой вход Ajax с представлением django.
views.py
def ajax_login(request):
"""
This view logs a user in using the POST data.
"""
if request.method == 'POST':
data = {}
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if (not user is None) and (user.is_active):
login(request, user)
# Set Session Expiry to 0 if user clicks "Remember Me"
if not request.POST.get('rem', None):
request.session.set_expiry(0)
data['success'] = "You have been successfully Logged In"
else:
data['error'] = "There was an error logging you in. Please Try again"
return HttpResponse(simplejson.dumps(data), mimetype="application/json")
В приведенном выше представлении мы выполнили обработку данных и отправили ответ JSON. Метод ajax будет выглядеть примерно так.
function ajaxLogin(){
var dataString = '&username=' + $('input[name=username]').val() +
'&password=' + $('input[name=password]').val() +
$.ajax({
type: "POST",
url: "/ajax_login/",
data: dataString,
success: function(data) {
alert(data);
}
});
return false;
}
Здесь метод успеха возвращает данные назад и alerts
для пользователя.
UPDATE
Я вижу, что вы определили метод ajaxPwchange()
, но я действительно не вижу, чтобы вы его вызывали в любом месте, и я думаю, поэтому страница все еще обновляется. Вы можете привязать метод ajaxPwchange()
к отправке кнопки onclick
следующим образом.
<input class="btn btn-primary" type="submit" value="submit" onclick="ajaxPwchange();" />
или привяжите его по методу document.ready
следующим образом:
$(document).ready(function(){
$('input.btn-primary').click(function(){
ajaxPwchange();
});
});
UPDATE2
div исчезает, потому что вы меняете div html
на объект json
непосредственно в следующем коде.
success: function(response) { // on success..
$('#modalchangepw').html(response); // update the DIV
}
вам лучше попробовать что-то вроде этого:
success: function(response) { // on success..
var jsonData = $.parseJSON(response);
$.each(response, function(){
$('#modalchangepw').append('<div class="message">' + $(this) + '</div>');
});
}
Ответ 2
Я приведу вам очень простой пример, чтобы вы могли понять концепцию, а затем использовать ту же концепцию, чтобы делать то, что вы пытаетесь сделать.
Я бы начал с создания обычного вида в views.py
def MyAjaxView(request):
if request.is_ajax():
if request.method == 'GET':
# If it was a GET
print request.GET
elif request.method == 'POST':
# Here we can access the POST data
print request.POST
else:
doSomeOtherStuff()
return render_to_response('mytemplate.html', some_context_maybe, context_instance=RequestContext(request))
В зависимости от того, что вы уже используете или что вы можете использовать, вы вызываете это с помощью javascript или библиотеки jQuery.
Предполагая, что у вас есть форма, которая выглядит как
<form id="myNameForm">
{% csrf_token %}
<input type="text" id="name" />
<input type="submit" value="submit" id="submitButton" />
</form>
теперь вы можете подключить это к функции ajax с помощью JavaScript, я буду использовать jQuery в качестве демонстрации, и я буду использовать метод jQuery ajax()
, поскольку он объясняет концепцию и переходит к post()
не должен быть слишком сложным.
<script>
$('#submitButton').click(function(event){
event.preventDefault(); //so that we stop normal form submit.
$.ajax(
url: 'myViewUrl',
type: 'post',
dataType: 'json',
data: $('form#myNameForm').serialize(),
success: function(data) {
doStuffWithDataHere(data);
}
);
});
</script>
Вы должны убедиться, что ваш urls.py
имеет URL-адрес для вашего нового представления.
Использование защиты CSRF также требует использования процессора CSRF, см. Комментарий BurhanKhalids для документации.