Answers:
即使这不完全符合SO精神,但我还是很喜欢这个问题,因为刚开始时我遇到了同样的麻烦,因此我将为您提供快速指南。显然,您不了解其背后的原理(不要将其视为冒犯,但如果您这样做,您将不会提出疑问)。
Django是服务器端的。这就意味着,比如说客户访问一个URL,您内部就有一个函数views
,该函数可以呈现他所看到的内容并以HTML返回响应。让我们将其分解为示例:
views.py:
def hello(request):
return HttpResponse('Hello World!')
def home(request):
return render_to_response('index.html', {'variable': 'world'})
index.html:
<h1>Hello {{ variable }}, welcome to my awesome site</h1>
urls.py:
url(r'^hello/', 'myapp.views.hello'),
url(r'^home/', 'myapp.views.home'),
这是最简单的用法示例。转到127.0.0.1:8000/hello
表示对hello()
函数的请求,转到127.0.0.1:8000/home
将返回index.html
并按要求替换所有变量(您现在可能已经知道了这一切)。
现在让我们谈谈AJAX。AJAX调用是执行异步请求的客户端代码。这听起来很复杂,但这仅意味着它会在后台为您提出请求,然后处理响应。因此,当您对某个URL进行AJAX调用时,您将获得与访问该位置的用户相同的数据。
例如,对的AJAX调用127.0.0.1:8000/hello
将返回与您访问它相同的东西。只有这一次,您才将其包含在JavaScript函数中,并且可以根据需要进行处理。让我们看一个简单的用例:
$.ajax({
url: '127.0.0.1:8000/hello',
type: 'get', // This is the default though, you don't actually need to always mention it
success: function(data) {
alert(data);
},
failure: function(data) {
alert('Got an error dude');
}
});
一般过程是这样的:
127.0.0.1:8000/hello
就像您打开一个新标签页并自己完成一样,呼叫将转到URL 。现在在这里会发生什么?您会收到有关“ hello world”的警报。如果您拨打AJAX到家里怎么办?同样,您会收到警告,说明<h1>Hello world, welcome to my awesome site</h1>
。
换句话说-AJAX调用没有新内容。它们只是让您在不离开页面的情况下让用户获取数据和信息的一种方法,它使您的网站设计流畅而整洁。您应该注意一些准则:
console.log
要调试的东西。我不会详细解释,只是在Google周围寻找它。这对您会非常有帮助。csrf_token
。通过AJAX调用,很多时候您想发送数据而不刷新页面。您可能会遇到一些麻烦,最后才想起那个-等待,您忘记了发送csrf_token
。这是AJAX-Django集成中的一个已知的初学者障碍,但是当您学习了如何使其变得更好时,它就像馅饼一样容易。这就是我想到的一切。这是一个广泛的主题,但是,可能没有足够的例子。只要按照自己的方式做,就慢慢地,最终会得到它。
csrf_token
,我们可以解决该方法吗?如果我们有一个示例函数,ajaxCall()
我们可以使用类似的传统方法<form onsubmit='ajaxCall();return false;'>
,对吗?
除了yuvi的出色答案之外,我想添加一个有关如何在Django中处理此问题的小示例(除了将要使用的所有js)。该示例使用AjaxableResponseMixin
并假设一个Author模型。
import json
from django.http import HttpResponse
from django.views.generic.edit import CreateView
from myapp.models import Author
class AjaxableResponseMixin(object):
"""
Mixin to add AJAX support to a form.
Must be used with an object-based FormView (e.g. CreateView)
"""
def render_to_json_response(self, context, **response_kwargs):
data = json.dumps(context)
response_kwargs['content_type'] = 'application/json'
return HttpResponse(data, **response_kwargs)
def form_invalid(self, form):
response = super(AjaxableResponseMixin, self).form_invalid(form)
if self.request.is_ajax():
return self.render_to_json_response(form.errors, status=400)
else:
return response
def form_valid(self, form):
# We make sure to call the parent's form_valid() method because
# it might do some processing (in the case of CreateView, it will
# call form.save() for example).
response = super(AjaxableResponseMixin, self).form_valid(form)
if self.request.is_ajax():
data = {
'pk': self.object.pk,
}
return self.render_to_json_response(data)
else:
return response
class AuthorCreate(AjaxableResponseMixin, CreateView):
model = Author
fields = ['name']
Django 1.6版的链接不再可用,已更新至1.11版
我写这封信是因为可接受的答案很旧,需要复习。
所以这就是我在2019年将Ajax与Django集成的方式:)让我们举一个实际的例子说明何时需要Ajax:-
可以说我有一个带有注册用户名的模型,并借助于Ajax我想知道给定的用户名是否存在。
的HTML:
<p id="response_msg"></p>
<form id="username_exists_form" method='GET'>
Name: <input type="username" name="username" />
<button type='submit'> Check </button>
</form>
阿贾克斯:
$('#username_exists_form').on('submit',function(e){
e.preventDefault();
var username = $(this).find('input').val();
$.get('/exists/',
{'username': username},
function(response){ $('#response_msg').text(response.msg); }
);
});
urls.py:
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('exists/', views.username_exists, name='exists'),
]
views.py:
def username_exists(request):
data = {'msg':''}
if request.method == 'GET':
username = request.GET.get('username').lower()
exists = Usernames.objects.filter(name=username).exists()
if exists:
data['msg'] = username + ' already exists.'
else:
data['msg'] = username + ' does not exists.'
return JsonResponse(data)
同样不推荐使用的render_to_response已被render取代,从Django 1.7起,而不是HttpResponse,我们使用JsonResponse进行Ajax响应。因为它带有JSON编码器,所以您不需要在返回响应对象之前对数据进行序列化,但HttpResponse
不建议使用。
简单而漂亮。您无需更改视图。Bjax处理所有链接。看看这个: Bjax
用法:
<script src="bjax.min.js" type="text/javascript"></script>
<link href="bjax.min.css" rel="stylesheet" type="text/css" />
最后,将其包含在html的HEAD中:
$('a').bjax();
有关更多设置,请在此处签出演示: Bjax演示
AJAX是执行异步任务的最佳方法。在任何网站建设中,进行异步调用都是很常见的事情。我们将以一个简短的例子来学习如何在Django中实现AJAX。我们需要使用jQuery,以便减少JavaScript。
这是Contact示例,这是最简单的示例,我用它来解释AJAX的基本知识及其在Django中的实现。在此示例中,我们将发出POST请求。我正在关注本文的示例之一:https : //djangopy.org/learn/step-up-guide-to-implement-ajax-in-django
models.py
首先,创建具有基本细节的Contact模型。
from django.db import models
class Contact(models.Model):
name = models.CharField(max_length = 100)
email = models.EmailField()
message = models.TextField()
timestamp = models.DateTimeField(auto_now_add = True)
def __str__(self):
return self.name
表格
创建上述模型的表单。
from django import forms
from .models import Contact
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
exclude = ["timestamp", ]
views.py
这些视图看起来类似于基于功能的基本创建视图,但是我们不使用render来返回,而是使用JsonResponse响应。
from django.http import JsonResponse
from .forms import ContactForm
def postContact(request):
if request.method == "POST" and request.is_ajax():
form = ContactForm(request.POST)
form.save()
return JsonResponse({"success":True}, status=200)
return JsonResponse({"success":False}, status=400)
urls.py
让我们创建以上视图的路线。
from django.contrib import admin
from django.urls import path
from app_1 import views as app1
urlpatterns = [
path('ajax/contact', app1.postContact, name ='contact_submit'),
]
模板
移至前端部分,呈现在封闭表单标签上方创建的表单以及csrf_token和Submit按钮。请注意,我们已经包含了jquery库。
<form id = "contactForm" method= "POST">{% csrf_token %}
{{ contactForm.as_p }}
<input type="submit" name="contact-submit" class="btn btn-primary" />
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Java脚本
现在让我们谈谈javascript部分,在表单提交中,我们发出POST类型的ajax请求,获取表单数据并发送到服务器端。
$("#contactForm").submit(function(e){
// prevent from normal form behaviour
e.preventDefault();
// serialize the form data
var serializedData = $(this).serialize();
$.ajax({
type : 'POST',
url : "{% url 'contact_submit' %}",
data : serializedData,
success : function(response){
//reset the form after successful submit
$("#contactForm")[0].reset();
},
error : function(response){
console.log(response)
}
});
});
这只是使用Django进行AJAX入门的基本示例,如果您想了解更多示例,可以阅读本文:https : //djangopy.org/learn/step-up-guide-to-在Django中实现ajax
我尝试在项目中使用AjaxableResponseMixin,但最终出现以下错误消息:
配置不正确:没有要重定向到的URL。在模型上提供一个URL或定义一个get_absolute_url方法。
这是因为当您向浏览器发送JSON请求时,CreateView将返回重定向响应,而不是返回HttpResponse。因此,我对进行了一些更改AjaxableResponseMixin
。如果该请求是ajax请求,则不会调用该super.form_valid
方法,而只是form.save()
直接调用。
from django.http import JsonResponse
from django import forms
from django.db import models
class AjaxableResponseMixin(object):
success_return_code = 1
error_return_code = 0
"""
Mixin to add AJAX support to a form.
Must be used with an object-based FormView (e.g. CreateView)
"""
def form_invalid(self, form):
response = super(AjaxableResponseMixin, self).form_invalid(form)
if self.request.is_ajax():
form.errors.update({'result': self.error_return_code})
return JsonResponse(form.errors, status=400)
else:
return response
def form_valid(self, form):
# We make sure to call the parent's form_valid() method because
# it might do some processing (in the case of CreateView, it will
# call form.save() for example).
if self.request.is_ajax():
self.object = form.save()
data = {
'result': self.success_return_code
}
return JsonResponse(data)
else:
response = super(AjaxableResponseMixin, self).form_valid(form)
return response
class Product(models.Model):
name = models.CharField('product name', max_length=255)
class ProductAddForm(forms.ModelForm):
'''
Product add form
'''
class Meta:
model = Product
exclude = ['id']
class PriceUnitAddView(AjaxableResponseMixin, CreateView):
'''
Product add view
'''
model = Product
form_class = ProductAddForm
当我们使用Django时:
Server ===> Client(Browser)
Send a page
When you click button and send the form,
----------------------------
Server <=== Client(Browser)
Give data back. (data in form will be lost)
Server ===> Client(Browser)
Send a page after doing sth with these data
----------------------------
如果要保留旧数据,则可以不使用Ajax。(页面将刷新)
Server ===> Client(Browser)
Send a page
Server <=== Client(Browser)
Give data back. (data in form will be lost)
Server ===> Client(Browser)
1. Send a page after doing sth with data
2. Insert data into form and make it like before.
After these thing, server will send a html page to client. It means that server do more work, however, the way to work is same.
或者您可以使用Ajax(页面不会刷新)
--------------------------
<Initialization>
Server ===> Client(Browser) [from URL1]
Give a page
--------------------------
<Communication>
Server <=== Client(Browser)
Give data struct back but not to refresh the page.
Server ===> Client(Browser) [from URL2]
Give a data struct(such as JSON)
---------------------------------
如果使用Ajax,则必须执行以下操作:
Django与Ajax不同。原因如下:
我认为,如果您想在任何地方使用ajax。当您首先需要使用数据初始化页面时,可以将Django与Ajax结合使用。但是在某些情况下,您只需要一个静态页面,而服务器上没有任何内容,则不需要使用Django模板。
如果您不认为Ajax是最佳实践。您可以使用Django模板来完成所有操作,例如动漫。
(我英文不太好)