Django:之传递数据给JS、Ajax和Ajax CSRF认证
Django传递数据给JS
有时候我们想把一个list或者dict传递给javascript,处理后显示到网页上,比如要用js进行可视化到数据。
请注意:如果是不处理,直接显示在网页上,用Django模版就可以了,请看前面的教程。
这里讲述两种方法:
一、页面加载完成后,在页面上操作,在页面上通过ajax方法得到新的数据(再向服务器发送一次请求)并显示在网页上,在这种情况适用于页面不刷新的情况下,动态加载一些内容。比如用户输入一个值或者点击某个地方,动态地把相应内容显示在网页上。
这种请详见下面Django Ajax一节的内容。
二、直接在视图函数(views.py中的函数)中渲染一个list或dict的内容,和网页其它部分一起显示到网页上(一次性地渲染,还是同一次请求)。
views.py
from __future__ import unicode_literals
from django.shortcuts import render def home(request):
List = ['吴老二博客', '渲染Json到模板']
return render(request, 'home.html', {'List': List})
home.html中的一部分
<script type="text/javascript">
var List = {{ List }};
alert(List);
</script>
需要注意的是,我们如果直接这么做,传递到js的时候,网页的内容会被转义得到的格式会报错。访问时会得到Uncaught SyntaxError: Unexpected token ILLEGAL
需要注意两点:
1、views.py中返回的函数中的值要用json.dumps()处理
2、在网页上要加一个safe过滤器。
views.py
# -*- coding: utf-8 -*- from __future__ import unicode_literals import json
from django.shortcuts import render def home(request):
List = ['吴老二博客', '渲染Json到模板']
Dict = {'site': '吴老二博客', 'author': '吴老二'}
return render(request, 'home.html', {
'List': json.dumps(List),
'Dict': json.dumps(Dict)
})
home.html只给出了js核心部分:
//列表
var List = {{ List|safe }};
//字典
var Dict = {{ Dict|safe }};
如果你对js比较熟悉,至此为止,下面的不用于看了,如果不太熟悉,可以参考下面的更详细的代码。
html完全代码及完整代码下载(最后面):
<!DOCTYPE html>
<html>
<head>
<title>欢迎光临 吴老二博客!</title>
<script src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<div id="list"> 学习 </div>
<div id='dict'></div>
<script type="text/javascript">
//列表
var List = {{ List|safe }}; //下面的代码把List的每一部分放到头部和尾部
$('#list').prepend(List[0]);
$('#list').append(List[1]); console.log('--- 遍历 List 方法 1 ---')
for(i in List){
console.log(i);// i为索引
} console.log('--- 遍历 List 方法 2 ---')
for (var i = List.length - 1; i >= 0; i--) {
// 鼠标右键,审核元素,选择 console 可以看到输入的值。
console.log(List[i]);
}; console.log('--- 同时遍历索引和内容,使用 jQuery.each() 方法 ---')
$.each(List, function(index, item){
console.log(index);
console.log(item);
}); // 字典
var Dict = {{ Dict|safe }};
console.log("--- 两种字典的取值方式 ---")
console.log(Dict['site']);
console.log(Dict.author); console.log("--- 遍历字典 ---");
for(i in Dict) {
console.log(i + Dict[i]);//注意,此处 i 为键值
}
</script>
</body>
</html>
完整代码下载:json.zip(基于Django 1.8,注意settings.py文件和低版本可能不兼容,其它部分相同)
Django Ajax
有时候我们需要在不刷新的情况下载入一些内容,在网页的基本知识中我们介绍了ajax技术。
在本文中讲解如何用Django来实现不刷新网页的情况下加载一些内容。
由于用jQuery实现ajax比较简单,所以我们用jQuery库来实现,想用原生的javascript的同学可以参考:ajax教程,下面也有例子提供下载。
本节有多个实例提供下载,通过看代码可以更快的学习。
第一节,源代码下载:ajax.zip
这里用Django表单第一节中的一个例子,我们要实现的是在不刷新的情况下显示计算结果到页面上。修改index.html文件
<!DOCTYPE html>
<html>
<body>
<p>请输入两个数字</p>
<form action="/add/" method="get">
a: <input type="text" id="a" name="a"> <br>
b: <input type="text" id="b" name="b"> <br>
<p>result: <span id='result'></span></p>
<button type="button" id='sum'>提交</button>
</form> <script src="http://apps.bdimg.com/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#sum").click(function(){
var a = $("#a").val();
var b = $("#b").val(); $.get("/add/",{'a':a,'b':b}, function(ret){
$('#result').html(ret)
})
});
});
</script>
</body>
</html>
在原来的基础上,在一些元素上加了id,以便于获取值和绑定数据,然后我们用了jQuery.get()方法,并用$(selector).html()方法将结果显示在页面上,如下图:
备注:关于请求头和request.is_ajax()方法使用
views.py中可以用request.is_ajax()方法判断是否是ajax请求,需要添加一个HTTP请求头:原生javascript:
xmlhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
用jQuery:
用 $.ajax 方法代替 $.get,因为 $.get 在 IE 中不会发送 ajax header
服务器端会将请求头的值全部大写,中划线改成下划线,并在非标准的头前面加上HTTP_,这个过程可以认为相当于以下Python代码:
STANDARD_HEADERS = ['REFER', 'HOST', ...] # just for example def handle_header(value):
value = value.replace('-', '_').upper() if value in STANDARD_HEADERS:
return value return 'HTTP_' + value
判断ajax方法,以及原生的javascript实现ajax的示例下载:views_ajax.zip
第二节,源代码下载:ajax_ist_dict.zip
更富在的例子,传递一个数组或字典到网页,由JS处理,再显示出来。
views.py
from django.http import HttpResponse
import json def ajax_list(request):
a = range(100)
return HttpResponse(json.dumps(a), content_type='application/json') def ajax_dict(request):
name_dict = {'twz': 'Love python and Django', 'zqxt': 'I am teaching Django'}
return HttpResponse(json.dumps(name_dict), content_type='application/json')
Django 1.7及以后到版本有更简单的方法(使用JsonResponse(官方文档)):
from django.http import JsonResponse def ajax_list(request):
a = range(100)
return JsonResponse(a, safe=False) def ajax_dict(request):
name_dict = {'twz': 'Love python and Django', 'zqxt': 'I am teaching Django'}
return JsonResponse(name_dict)
在django 1.6及以前的旧版本中可以自己写一个JsonResponse方法,如下:
from django.http import HttpResponse import json class JsonResponse(HttpResponse):
def __init__(self,
content={},
mimetype=None,
status=None,
content_type='application/json'): super(JsonResponse, self).__init__(
json.dumps(content),
mimetype=mimetype,
status=status,
content_type=content_type)
写好厚,我们在urls.py中添加以下两行:
url(r'^ajax_list/$', 'tools.views.ajax_list', name='ajax-list'),
url(r'^ajax_dict/$', 'tools.views.ajax_dict', name='ajax-dict'),
我们访问对应的网址会看到输出值:
下一步就是在无刷新的情况下把内容加载到网页了,我们修改一下首页的模版index.html
<!DOCTYPE html>
<html>
<body>
<p>请输入两个数字</p>
<form action="/add/" method="get">
a: <input type="text" id="a" name="a"> <br>
b: <input type="text" id="b" name="b"> <br>
<p>result: <span id='result'></span></p>
<button type="button" id='sum'>提交</button>
</form> <div id="dict">Ajax 加载字典</div>
<p id="dict_result"></p> <div id="list">Ajax 加载列表</div>
<p id="list_result"></p> <script src="http://apps.bdimg.com/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
// 求和 a + b
$("#sum").click(function(){
var a = $("#a").val();
var b = $("#b").val(); $.get("/add/",{'a':a,'b':b}, function(ret){
$('#result').html(ret);
})
}); // 列表 list
$('#list').click(function(){
$.getJSON('/ajax_list/',function(ret){
//返回值 ret 在这里是一个列表
for (var i = ret.length - 1; i >= 0; i--) {
// 把 ret 的每一项显示在网页上
$('#list_result').append(' ' + ret[i])
};
})
}) // 字典 dict
$('#dict').click(function(){
$.getJSON('/ajax_dict/',function(ret){
//返回值 ret 在这里是一个字典
$('#dict_result').append(ret.twz + '<br>');
// 也可以用 ret['twz']
})
})
});
</script>
</body>
</html>
技能提升:getJSON中写的对应网址,用urls.py中的name来获取是一个更好的方法!
标签:{% url 'name' %}
<script>
$(document).ready(function(){
// 求和 a + b
$("#sum").click(function(){
var a = $("#a").val();
var b = $("#b").val(); $.get("{% url 'add' %}",{'a':a,'b':b}, function(ret){
$('#result').html(ret);
})
}); // 列表 list
$('#list').click(function(){
$.getJSON("{% url 'ajax-list' %}",function(ret){
//返回值 ret 在这里是一个列表
for (var i = ret.length - 1; i >= 0; i--) {
// 把 ret 的每一项显示在网页上
$('#list_result').append(' ' + ret[i])
};
})
}) // 字典 dict
$('#dict').click(function(){
$.getJSON("{% url 'ajax-dict' %}",function(ret){
//返回值 ret 在这里是一个字典
$('#dict_result').append(ret.twz + '<br>');
// 也可以用 ret['twz']
})
})
});
</script>
这样做最大的好处就是在修改urls.py中的网址后,不用改模版中对应的网址。
补充:如果是一个复杂的列表 或 字典,因为比如如下信息:
person_info_dict = [
{"name":"laowu", "age":20},
{"name":"wulaoer", "age":24},
{"name":"laoer", "age":33},
]
这样我们遍历列表的时候,每次遍历得到一个字典,再用字典的方法去处理,当然有更简单的遍历方法:用$.each()方法代替for循环,html代码(jQuery)
$.getJSON('ajax-url-to-json', function(ret) {
$.each(ret, function(i,item){
// i 为索引,item为遍历值
});
});
最后,附上一个返回图片并显示的ajax实例:
Django Ajax CSRF认证
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“one click attack”或者session riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范对资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
Django中自带来防止CSRF攻击的功能,但是一些新手不知道如何使用,给自己编程带来了麻烦。常常会出现下面Django csrf token missing or incorrect的错误。
GET请求不需要CSRF认证,POST请求需要正确认证才能得到正确的返回结果。一般在POST表单中加入{% csrf_token %}
<form method="POST" action="/post-url/">
{% csrf_token %} <input name='zqxt' value="吴老二博客Django技术">
</form>
如果使用Ajax调用的时候,就要麻烦一些。需要注意一下几点:
1、在视图中使用render(而不要使用render_to_response)
2、使用jQuery的ajax或者post之前加入这个js代码:
jQuery(document).ajaxSend(function(event, xhr, settings) {
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function sameOrigin(url) {
// url could be relative or scheme relative or absolute
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
// Allow absolute or scheme relative URLs to same origin
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
// or any other URL that isn't scheme relative or absolute i.e relative.
!(/^(\/\/|http:|https:).*/.test(url));
}
function safeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
} if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
});
或者更为优雅简洁的代码(不能写在.js 中,要直接写在模版文件中):
$.ajaxSetup({
data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});
这样之后,就可以像原来一样的使用jQuery.ajax()和jQuery.post()了
Django:之传递数据给JS、Ajax和Ajax CSRF认证的更多相关文章
- Django:django后台传递数据到js中
#奇怪传递字典时前台接收不到???datalist= [{'site': '自强学堂', 'author': '涂伟忠'}]#只要列表能接收# datalist=[[93, 93, 0, 100.01 ...
- django 前后台传递数据
前几天,我们完成了用django orm对数据进行操作.接下来,我们要把数据从后台放到前台. 1.用get方式传值 get:就是在URL拼接字符串,在后台,用request.get方式取 2.用pos ...
- Django传递数据给JS
这里讲述两种方法: 一,页面加载完成后,在页面上操作,在页面上通过 ajax 方法得到新的数据(再向服务器发送一次请求)并显示在网页上,这种情况适用于页面不刷新的情况下,动态加载一些内容.比如用户输入 ...
- python学习-- Django传递数据给JS
var List = {{ List|safe }};//safe 必须存在
- Django与JS交互的示例代码-django js 获取 python 字典-Django 前后台的数据传递
Django与JS交互的示例代码 Django 前后台的数据传递 https://www.cnblogs.com/xibuhaohao/p/10192052.html 应用一:有时候我们想把一个 li ...
- Django 仿ajax传递数据(Django十)
之前用form表单传递数据,没有遇到任何问题 具体见:https://blog.csdn.net/qq_38175040/article/details/104867747 然后现在我想用ajax传递 ...
- Django 前后台的数据传递
Django 从后台往前台传递数据时有多种方法可以实现. 最简单的后台是这样的: from django.shortcuts import render def main_page(request): ...
- Django 前后台的数据传递示列
Django 前后台的数据传递的方法 Django 从后台往前台传递数据时有多种方法可以实现. 最简单的后台是这样的: ? 1 2 3 4 from django.shortcuts import r ...
- Django【第24篇】:JS实现的ajax和同源策略
JS实现的ajax和同源策略 一.回顾jQuery实现的ajax 首先说一下ajax的优缺点 优点: AJAX使用Javascript技术向服务器发送异步请求: AJAX无须刷新整个页面: 因为服务器 ...
随机推荐
- Python编程工具IDLE快捷键
IDLE编辑器快捷键 自动补全代码 Alt+/(查找编辑器内已经写过的代码来补全) 补全提示 Ctrl+Shift+space(默认与输入法冲突,修改之) (方 ...
- KVM guest caching modes
kvm中host和guest各自维护自己的page caches,使得内存中有两份缓存数据.host的缓存为page cache可以理解为读缓存,guest的缓存为disk write cache,可 ...
- mysql 用户权限设置
windows使用的zip包的mysql.配置成功后,root用户没有权限,需要进行权限分配.管理员运行cmd,执行以下命令,进入mysql. mysql -u root -p Passwd Pass ...
- 为什么new的普通数组用delete 和 delete[]都能正确释放
由同事推荐的一篇博客: 为何new出的对象数组必须要用delete[]删除,而普通数组delete和delete[]都一样-------_CrtMemBlockHeader 文章解释了delete 内 ...
- 【转】关于spring集合对象的补充
<span style="font-size:18px;">关于spring集合对象的补充 spring2.0中对集合对象有了改进,新增了一个<util>标 ...
- intellij idea 12 搭建maven web项目
原来公司一直使用eclipse,突然使用这个intellij还真有点不习惯,等用了一段时间才发现的确好用,因为也是刚开始用,所以很多不理解的地方,搭建一个项目从头好好了解下intellij 最开始的m ...
- AngularJs应用
引用angularjs文件 AngularJS 应用组成如下:View(视图), 即 HTML.Model(模型), 当前视图中可用的数据.Controller(控制器), 即 JavaScript ...
- Mr. Kitayuta vs. Bamboos
Mr. Kitayuta vs. Bamboos 题目链接:http://codeforces.com/problemset/problem/505/E 参考:http://blog.csdn.net ...
- firebug的调试,console
console.log() console.warn() 警告 console.error() 错误 console.group() 分组 console.grounpEnd() 分组结束 co ...
- JObject对json的操作
一,需去程序集添加using Newtonsoft.Json.Linq;引用 using System; using System.Collections.Generic; using System. ...