Python 如何将 Ajax 与 Django 应用程序集成?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20306981/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I integrate Ajax with Django applications?
提问by tjons
I am new to Django and pretty new to Ajax. I am working on a project where I need to integrate the two. I believe that I understand the principles behind them both, but have not found a good explanation of the two together.
我是 Django 的新手,也是 Ajax 的新手。我正在做一个项目,我需要将两者结合起来。我相信我理解它们背后的原理,但还没有找到对两者的很好的解释。
Could someone give me a quick explanation of how the codebase must change with the two of them integrating together?
有人可以快速解释一下代码库必须如何随着它们两个集成在一起而改变吗?
For example, can I still use the HttpResponsewith Ajax, or do my responses have to change with the use of Ajax? If so, could you please provide an example of how the responses to the requests must change? If it makes any difference, the data I am returning is JSON.
例如,我是否仍然可以使用HttpResponsewith Ajax,或者我的响应是否必须随着 Ajax 的使用而改变?如果是这样,您能否举例说明对请求的响应必须如何改变?如果它有任何区别,我返回的数据是 JSON。
采纳答案by yuvi
Even though this isn't entirely in the SO spirit, I love this question, because I had the same trouble when I started, so I'll give you a quick guide. Obviously you don't understand the principles behind them (don't take it as an offense, but if you did you wouldn't be asking).
尽管这并不完全符合 SO 精神,但我喜欢这个问题,因为我在开始时遇到了同样的问题,所以我会给你一个快速指南。显然你不理解它们背后的原则(不要认为这是冒犯,但如果你理解了,你就不会问了)。
Django is server-side. It means, say a client goes to a URL, you have a function inside viewsthat renders what he sees and returns a response in HTML. Let's break it up into examples:
Django 是服务器端的。这意味着,假设客户端访问一个 URL,您在内部有一个函数views,可以呈现他所看到的内容并以 HTML 格式返回响应。让我们把它分成几个例子:
views.py:
视图.py:
def hello(request):
return HttpResponse('Hello World!')
def home(request):
return render_to_response('index.html', {'variable': 'world'})
index.html:
索引.html:
<h1>Hello {{ variable }}, welcome to my awesome site</h1>
urls.py:
网址.py:
url(r'^hello/', 'myapp.views.hello'),
url(r'^home/', 'myapp.views.home'),
That's an example of the simplest of usages. Going to 127.0.0.1:8000/hellomeans a request to the hello()function, going to 127.0.0.1:8000/homewill return the index.htmland replace all the variables as asked (you probably know all this by now).
这是最简单用法的一个例子。Going to127.0.0.1:8000/hello表示对hello()函数的请求,Going to127.0.0.1:8000/home将返回index.html并替换所询问的所有变量(您现在可能已经知道了所有这些)。
Now let's talk about AJAX. AJAX calls are client-side code that does asynchronous requests. That sounds complicated, but it simply means it does a request for you in the background and then handles the response. So when you do an AJAX call for some URL, you get the same data you would get as a user going to that place.
现在让我们谈谈AJAX。AJAX 调用是执行异步请求的客户端代码。这听起来很复杂,但这只是意味着它在后台为您发出请求,然后处理响应。因此,当您对某个 URL 执行 AJAX 调用时,您将获得与用户访问该地点时获得的数据相同的数据。
For example, an AJAX call to 127.0.0.1:8000/hellowill return the same thing it would as if you visited it. Only this time, you have it inside a JavaScript function and you can deal with it however you'd like. Let's look at a simple use case:
例如,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');
}
});
The general process is this:
一般流程是这样的:
- The call goes to the URL
127.0.0.1:8000/helloas if you opened a new tab and did it yourself. - If it succeeds (status code 200), do the function for success, which will alert the data received.
- If fails, do a different function.
- 调用转到 URL
127.0.0.1:8000/hello,就像您打开一个新选项卡并自己完成一样。 - 如果成功(状态码200),执行成功函数,会提示收到的数据。
- 如果失败,请执行不同的功能。
Now what would happen here? You would get an alert with 'hello world' in it. What happens if you do an AJAX call to home? Same thing, you'll get an alert stating <h1>Hello world, welcome to my awesome site</h1>.
现在这里会发生什么?您会收到带有“hello world”的警报。如果您使用 AJAX 调用 home 会发生什么?同样的事情,你会收到一条警告,说明<h1>Hello world, welcome to my awesome site</h1>。
In other words - there's nothing new about AJAX calls. They are just a way for you to let the user get data and information without leaving the page, and it makes for a smooth and very neat design of your website. A few guidelines you should take note of:
换句话说 - AJAX 调用并没有什么新鲜事。它们只是让用户在不离开页面的情况下获取数据和信息的一种方式,它使您的网站设计流畅且非常整洁。您应该注意的一些准则:
- Learn jQuery. I cannot stress this enough. You're gonna have to understand it a little to know how to handle the data you receive. You'll also need to understand some basic JavaScript syntax (not far from python, you'll get used to it). I strongly recommend Envato's video tutorials for jQuery, they are great and will put you on the right path.
- When to use JSON?. You're going to see a lot of examples where the data sent by the Django views is in JSON. I didn't go into detail on that, because it isn't important howto do it (there are plenty of explanations abound) and a lot more important when. And the answer to that is - JSON data is serialized data. That is, data you can manipulate. Like I mentioned, an AJAX call will fetch the response as if the user did it himself. Now say you don't want to mess with all the html, and instead want to send data (a list of objects perhaps). JSON is good for this, because it sends it as an object (JSON data looks like a python dictionary), and then you can iterate over it or do something else that removes the need to sift through useless html.
- Add it last. When you build a web app and want to implement AJAX - do yourself a favor. First, build the entire app completely devoid of any AJAX. See that everything is working. Then, and only then, start writing the AJAX calls. That's a good process that helps you learn a lot as well.
- Use chrome's developer tools. Since AJAX calls are done in the background it's sometimes very hard to debug them. You should use the chrome developer tools (or similar tools such as firebug) and
console.logthings to debug. I won't explain in detail, just google around and find out about it. It would be very helpful to you. - CSRF awareness. Finally, remember that post requests in Django require the
csrf_token. With AJAX calls, a lot of times you'd like to send data without refreshing the page. You'll probably face some trouble before you'd finally remember that - wait, you forgot to send thecsrf_token. This is a known beginner roadblock in AJAX-Django integration, but after you learn how to make it play nice, it's easy as pie.
- 学习jQuery。我怎么强调这一点都不为过。您必须稍微了解它才能知道如何处理您收到的数据。您还需要了解一些基本的 JavaScript 语法(距离 Python 不远,您会习惯的)。我强烈推荐Envato 的 jQuery 视频教程,它们很棒,会让你走上正确的道路。
- 何时使用 JSON?. 您将看到很多示例,其中 Django 视图发送的数据采用 JSON 格式。我没有详细说明,因为如何做到这一点并不重要(有很多解释比比皆是),更重要的是当. 答案是 - JSON 数据是序列化数据。也就是说,您可以操作的数据。就像我提到的,AJAX 调用将获取响应,就像用户自己做的一样。现在说你不想弄乱所有的 html,而是想发送数据(也许是一个对象列表)。JSON 对此很有用,因为它将它作为对象发送(JSON 数据看起来像 Python 字典),然后您可以对其进行迭代或执行其他操作,从而无需筛选无用的 html。
- 最后添加。当您构建 Web 应用程序并想要实现 AJAX 时 - 帮自己一个忙。首先,构建完全没有任何 AJAX 的整个应用程序。看到一切正常。然后,并且只有在那时,才开始编写 AJAX 调用。这是一个很好的过程,也可以帮助您学到很多东西。
- 使用 chrome 的开发者工具。由于 AJAX 调用是在后台完成的,因此有时很难调试它们。您应该使用 chrome 开发人员工具(或类似工具,例如 firebug)和
console.log调试工具。我不会详细解释,只是谷歌搜索并了解它。这对你会很有帮助。 - CSRF 意识。最后,请记住 Django 中的 post 请求需要
csrf_token. 对于 AJAX 调用,很多时候您希望在不刷新页面的情况下发送数据。在您最终记住之前,您可能会遇到一些麻烦 - 等等,您忘记发送csrf_token. 这是 AJAX-Django 集成中一个众所周知的初学者障碍,但是在您学会如何让它玩得更好之后,它就像馅饼一样简单。
That's everything that comes to my head. It's a vast subject, but yeah, there's probably not enough examples out there. Just work your way there, slowly, you'll get it eventually.
这就是我想到的一切。这是一个庞大的主题,但是是的,可能没有足够的例子。只要按照自己的方式工作,慢慢地,你最终会得到它。
回答by Wtower
Further from yuvi's excellent answer, I would like to add a small specific example on how to deal with this within Django (beyond any js that will be used). The example uses AjaxableResponseMixinand assumes an Author model.
除了 yuvi 的出色回答之外,我想添加一个关于如何在 Django 中处理此问题的具体示例(除了将使用的任何 js)。该示例使用AjaxableResponseMixin并假定作者模型。
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']
Source: Django documentation, Form handling with class-based views
The link to version 1.6 of Django is no longer available updated to version 1.11
Django 1.6 版的链接不再可用,更新到 1.11 版
回答by endur
Simple and Nice. You don't have to change your views. Bjax handles all your links. Check this out: Bjax
简单而美好。你不必改变你的看法。Bjax 处理您的所有链接。看看这个: Bjax
Usage:
用法:
<script src="bjax.min.js" type="text/javascript"></script>
<link href="bjax.min.css" rel="stylesheet" type="text/css" />
Finally, include this in the HEAD of your html:
最后,将其包含在您的 html 的 HEAD 中:
$('a').bjax();
For more settings, checkout demo here: Bjax Demo
回答by Enix
I have tried to use AjaxableResponseMixinin my project, but had ended up with the following error message:
我曾尝试在我的项目中使用AjaxableResponseMixin,但最终出现以下错误消息:
ImproperlyConfigured: No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model.
ImproperlyConfigured:没有要重定向到的 URL。在模型上提供一个 url 或定义一个 get_absolute_url 方法。
That is because the CreateView will return a redirect responseinstead of returning a HttpResponse when you to send JSON request to the browser. So I have made some changes to the AjaxableResponseMixin. If the request is an ajax request, it will not call the super.form_validmethod, just call the form.save()directly.
这是因为当您向浏览器发送 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
回答by Ahtisham
I am writing this because the accepted answer is pretty old, it needs a refresher.
我写这个是因为接受的答案已经很旧了,需要复习一下。
So this is how I would integrate Ajax with Django in 2019 :) And lets take a real example of when we would need Ajax :-
所以这就是我在 2019 年将 Ajax 与 Django 集成的方式 :) 让我们举一个真实的例子来说明我们何时需要 Ajax :-
Lets say I have a model with registered usernames and with the help of Ajax I wanna know if a given username exists.
假设我有一个带有注册用户名的模型,在 Ajax 的帮助下,我想知道给定的用户名是否存在。
html:
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>
ajax:
阿贾克斯:
$('#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:
网址.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:
视图.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)
Also render_to_responsewhich is deprecated and has been replaced by renderand from Django 1.7 onwards instead of HttpResponsewe use JsonResponsefor ajax response. Because it comes with a JSON encoder, so you don't need to serialize the data before returning the response object but HttpResponseis not deprecated.
还有render_to_response已被弃用并已被render取代,并且从 Django 1.7 开始,我们使用JsonResponse代替HttpResponse进行 ajax 响应。因为它带有一个 JSON 编码器,所以你不需要在返回响应对象之前序列化数据但不推荐使用。HttpResponse
回答by Jai Singhal
AJAX is the best way to do asynchronous tasks. Making asynchronous calls is something common in use in any website building. We will take a short example to learn how we can implement AJAX in Django. We need to use jQuery so as to write less javascript.
AJAX 是执行异步任务的最佳方式。进行异步调用在任何网站建设中都是常见的。我们将通过一个简短的示例来了解如何在 Django 中实现 AJAX。我们需要使用 jQuery 来编写更少的 javascript。
This is Contactexample, which is the simplest example, I am using to explain the basics of AJAX and its implementation in Django. We will be making POST request in this example. I am following one of the example of this post: https://djangopy.org/learn/step-up-guide-to-implement-ajax-in-django
这是Contact示例,这是最简单的示例,我用来解释 AJAX 的基础知识及其在 Django 中的实现。我们将在这个例子中发出 POST 请求。我正在关注这篇文章的示例之一:https: //djangopy.org/learn/step-up-guide-to-implement-ajax-in-django
models.py
模型.py
Let's first create the model of Contact, having basic details.
让我们首先创建 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
forms.py
表格.py
Create the form for the above model.
为上述模型创建表单。
from django import forms
from .models import Contact
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
exclude = ["timestamp", ]
views.py
视图.py
The views look similar to the basic function-based create view, but instead of returning with render, we are using JsonResponse response.
这些视图看起来类似于基于函数的基本创建视图,但我们使用的是 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
网址.py
Let's create the route of the above view.
让我们创建上述视图的路由。
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'),
]
template
模板
Moving to frontend section, render the form which was created above enclosing form tag along with csrf_token and submit button. Note that we have included the jquery library.
移至前端部分,呈现在封闭表单标记上方创建的表单以及 csrf_token 和提交按钮。请注意,我们已经包含了 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>
Javascript
Javascript
Let's now talk about javascript part, on the form submit we are making ajax request of type POST, taking the form data and sending to the server side.
现在让我们谈谈 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)
}
});
});
This is just a basic example to get started with AJAX with django, if you want to get dive with several more examples, you can go through this article: https://djangopy.org/learn/step-up-guide-to-implement-ajax-in-django
这只是使用 django 开始使用 AJAX 的一个基本示例,如果您想深入了解更多示例,可以阅读本文:https: //djangopy.org/learn/step-up-guide-to-在 Django 中实现 ajax
回答by kyakya
When we use Django:
当我们使用 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
----------------------------
If you want to keep old data, you can do it without Ajax. (Page will be refreshed)
如果要保留旧数据,可以不用 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.
Or you can do with Ajax (Page will be not refreshed)
或者你可以用 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)
---------------------------------
If you use Ajax, you must do these:
如果您使用 Ajax,则必须执行以下操作:
- Initial a HTML page using URL1 (we usually initial page by Django template). And then server send client a html page.
- Use Ajax to communicate with server using URL2. And then server send client a data struct.
- 使用 URL1 初始化一个 HTML 页面(我们通常通过 Django 模板初始化页面)。然后服务器向客户端发送一个 html 页面。
- 使用 Ajax 与使用 URL2 的服务器通信。然后服务器向客户端发送一个数据结构。
Django is different from Ajax. The reason for this is as follows:
Django 与 Ajax 不同。原因如下:
- The thing return to client is different. The case of Django is HTML page. The case of Ajax is data struct.
- Django is good at creating something, but it only can create once, it cannot change anything. Django is like anime, consist of many picture. By contrast, Ajax is not good at creating sth but good at change sth in exist html page.
- 返回给客户的东西是不同的。Django 的案例是 HTML 页面。Ajax 的案例是数据结构。
- Django 擅长创造一些东西,但它只能创造一次,它不能改变任何东西。Django 就像动漫一样,由许多图片组成。相比之下,Ajax 不擅长在现有的 html 页面中创建某物而擅长改变某物。
In my opinion, if you would like to use ajax everywhere. when you need to initial a page with data at first, you can use Django with Ajax. But in some case, you just need a static page without anything from server, you need not use Django template.
在我看来,如果你想在任何地方使用 ajax。当您需要首先使用数据初始化页面时,您可以将 Django 与 Ajax 结合使用。但是在某些情况下,您只需要一个没有来自服务器的任何内容的静态页面,您不需要使用 Django 模板。
If you don't think Ajax is the best practice. you can use Django template to do everything, like anime.
如果您不认为 Ajax 是最佳实践。你可以使用 Django 模板来做任何事情,比如动漫。
(My English is not good)
(我的英语不是很好)

