如何将Ajax与Django应用程序集成?
我是Django的新手,对Ajax来说很新颖。 我正在做一个项目,我需要整合这两个项目。 我相信我理解他们背后的原则,但是还没有find一个好的解释。
有人能够简单地解释一下代码库必须如何改变吗?
例如,我是否仍然可以使用带有Ajax的HttpResponse
,或者使用Ajax来更改我的响应? 如果是这样,请您举例说明如何对请求的回应做出改变? 如果它有什么不同,我要返回的数据是JSON。
尽pipe这并不完全符合SO的精神,但我喜欢这个问题,因为我在开始时遇到同样的麻烦,所以我会给你一个快速的指导。 显然你不明白他们背后的原则(不要把它作为一种冒犯,但如果你这样做,你不会问)。
Django是服务器端的。 这意味着,说一个客户去url,你有一个函数内部的视图,呈现他所看到的,并在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
并按照问题(你可能现在已经知道所有这些)来replace所有的variables。
现在我们来谈谈AJAX。 AJAX调用是执行asynchronous请求的客户端代码。 这听起来很复杂,但它意味着它在后台为你做了一个请求,然后处理响应。 所以当你做一个url的AJAX调用时,你会得到和用户去那个地方相同的数据。
例如,对127.0.0.1:8000/hello
的ajax调用将返回与您访问它相同的内容。 只有这一次,你有它在一个JSfunction,你可以处理它,但是你想。 我们来看一个简单的用例:
$.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,就好像你打开了一个新的标签,自己做的。 - 如果成功(状态码200),则执行成功的function,这将提醒收到的数据。
- 如果失败,请执行其他function。
现在会发生什么? 你会得到一个“hello world”的提醒。 如果你打电话回家,会发生什么? 同样的事情,你会看到<h1>Hello world, welcome to my awesome site</h1>
。
换句话说 – AJAX调用没有什么新鲜之处。 它们只是让用户在不离开页面的情况下获取数据和信息的一种方式,并且可以为您的网站devise一个stream畅而整洁的devise。 你应该注意一些准则:
- 学习jQuery 。 我不能强调这一点。 知道如何处理您收到的数据,您将需要了解一点。 你还需要了解一些基本的javascript语法(离python不远,你会习惯的)。 我强烈推荐Envato针对jQuery的video教程 ,它们很棒,会让你走上正确的道路。
- 何时使用JSON? 。 你会看到很多例子,Django视图发送的数据都是以JSON的forms出现的。 我没有详细说明这一点,因为如何做到这一点并不重要(有大量的解释),更重要的是什么时候 。 答案就是 – JSON数据是序列化的数据。 也就是说,你可以操纵的数据。 就像我所提到的那样,一个AJAX调用将会像用户自己做的那样获取响应。 现在说你不想搞乱所有的html,而是想发送数据(可能是一个对象列表)。 JSON对此非常有用,因为它将它作为对象发送(JSON数据看起来像一个Python字典),然后您可以遍历它或者执行其他操作,从而无需筛选无用的html。
- 最后添加它 。 当你build立一个networking应用程序,并希望实现AJAX – 帮自己一个忙。 首先,build立完全没有任何AJAX的应用程序。 看到一切正常。 然后,只有这样,才能开始编写AJAX调用。 这是一个很好的过程,可以帮助你学习很多东西。
- 使用chrome的开发者工具 。 由于AJAX调用是在后台完成的,有时很难debugging它们。 你应该使用chrome开发工具(或类似的工具,如萤火虫)和
console.log
东西进行debugging。 我不会详细解释,只是谷歌周围,了解它。 这对你很有帮助。 - CSRF意识 。 最后,请记住,Django中的post请求需要
csrf_token
。 使用AJAX调用,很多时候您都希望发送数据而不刷新页面。 在你终于记住之前,你可能会遇到一些麻烦 – 等等,你忘了发送csrf_token
。 在AJAX-Django集成中,这是一个已知的初学者障碍,但在学习如何使它发挥出色之后,这很容易。
这就是我脑海中的一切。 这是一个很大的问题,但是,这里可能没有足够的例子。 只要在那里工作,慢慢地,你会最终得到它。
进一步从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 (eg 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文档,使用基于类的视图进行表单处理
简单而好看。 你不必改变你的观点。 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演示
我试图在我的项目中使用AjaxableResponseMixin ,但结束了以下错误信息:
错误地configuration:没有URLredirect到。 在模型上提供一个url或定义一个get_absolute_url方法。
这是因为CreateView将返回一个redirect响应,而不是返回一个HttpResponse给你发送JSON结果给浏览器。 所以我对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 (eg 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