拾伍 ● Ajax技术
一 ● Ajax定义
Ajax: 异步的 JavaScript 和 XML (Asynchronous+Javascript+XML) 通过Ajax, 我们可以在不重新加载整个网页的情况下,对网页的某部分进行更新(重新加载整个网页是: 雕版印刷, 对网页的某个部分进行更新: 活字印刷) |
※ 异步: 向服务器发送请求的时候,我们不必等待结果,而是可以同时做其他的事情,等到有了结果我们可以再来处理这个事 |
二 ● 常见Ajax技术
1 ● $.post()、$.get()、$.load()是一些简单Ajax方法(用得较少)
<html> <head> <script type="text/javascript" src="/jquery/jquery.js"></script> <script type="text/javascript"> $(document).ready(function () { $("#b01").click(function () { $('#myDiv').load('/jquery/test1.txt'); }); }); </script> </head> <body>
<div id="myDiv"><h2>通过 AJAX 改变文本</h2></div> <button id="b01" type="button">改变内容</button>
</body> </html> |
2 ● jQuery.ajax(), 即$.ajax(), 能处理复杂的逻辑
一般使用格式 $("#login_btn").on("click", function () { $.ajax({ url: "/foo/", type: 'POST', data: 键值对(data是引用数据类型), success: function(data){}, dataType: dataType }); }); |
$.ajax()的参数是一个字典, 它的键包括: url→必需,(默认为当前页地址)指向要操作的路径 type→可选, 请求方式("POST", "GET") data→可选, 键值对(data是引用数据类型), 连同请求发送到服务器。 success→可选, 请求成功时执行的回调函数。 dataType→可选, 规定预期的服务器响应的数据类型。若未指定, 则智能判断(xml、json、script 或 html)。 |
※ 如果要处理 $.ajax() 得到的数据,则需要使用回调函数:beforeSend、error、dataFilter、success、complete。 |
※ jQuery.ajax()的参数列表
参数名 |
类型 |
描述 |
url |
String |
(默认: 当前页地址) 发送请求的地址。 |
type |
String |
(默认: "GET") 请求方式 ("POST" 或 "GET"),默认为 "GET"。注意:其它HTTP 请求方法,如 PUT 和 DELETE 也可以使用,但仅部分浏览器支持。 |
timeout |
Number |
设置请求超时时间(毫秒)。此设置将覆盖全局设置。 |
async |
Boolean |
(默认: true) 默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false。注意,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行。 |
beforeSend |
Function |
发送请求前可修改 XMLHttpRequest 对象的函数,如添加自定义 HTTP头。XMLHttpRequest 对象是唯一的参数。 function (XMLHttpRequest) { this; // the options for this ajax request } |
cache |
Boolean |
(默认: true) jQuery 1.2 新功能,设置为 false 将不会从浏览器缓存中加载请求信息。 |
complete |
Function |
请求完成后回调函数 (请求成功或失败时均调用)。参数:XMLHttpRequest 对象,成功信息字符串。 function (XMLHttpRequest, textStatus) { this; // the options for this ajax request } |
contentType |
String |
(默认: "application/x-www-form-urlencoded") 发送信息至服务器时内容编码类型。默认值适合大多数应用场合。 ※ from的enctype属性的默认值也是application/x-www-form-urlencoded |
data |
Object, String |
发送到服务器的数据。将自动转换为请求字符串格式。GET 请求中将附加在 URL 后。查看 processData 选项说明以禁止此自动转换。必须为Key/Value 格式。如果为数组,jQuery 将自动为不同值对应同一个名称。如 {foo:["bar1", "bar2"]} 转换为 '&foo=bar1&foo=bar2'。 |
dataType |
String |
预期服务器返回的数据类型。如果不指定,jQuery 将自动根据 HTTP 包MIME 信息返回 responseXML 或 responseText,并作为回调函数参数传递,可用值: "xml": 返回 XML 文档,可用 jQuery 处理。 "html": 返回纯文本 HTML 信息;包含 script 元素。 "script": 返回纯文本 JavaScript 代码。不会自动缓存结果。 "json": 返回 JSON 数据。 "jsonp": JSONP 格式。使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。 |
error |
Function |
(默认: 自动判断 (xml 或 html)) 请求失败时将调用此方法。这个方法有三个参数:XMLHttpRequest 对象,错误信息,(可能)捕获的错误对象。 function (XMLHttpRequest, textStatus, errorThrown) { // 通常情况下textStatus和errorThown只有其中一个有值 this; // the options for this ajax request } |
global |
Boolean |
(默认: true) 是否触发全局 AJAX 事件。设置为 false 将不会触发全局 AJAX事件,如 ajaxStart 或 ajaxStop 。可用于控制不同的Ajax事件 |
ifModified |
Boolean |
(默认: false) 仅在服务器数据改变时获取新数据。使用 HTTP 包 Last-Modified 头信息判断。 |
processData |
Boolean |
(默认: true) 默认情况下,发送的数据将被转换为对象(技术上讲并非字符串) 以配合默认内容类型 "application/x-www-form-urlencoded"。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。 |
success |
Function |
请求成功后回调函数。这个方法有两个参数:服务器返回数据,返回状态 function (data, textStatus) { // data could be xmlDoc, jsonObj, html, text, etc... this; // the options for this ajax request } |
3 ● jQuery的serialize() 方法
语法: $(selector).serialize() serialize() 方法通过序列化表单值创建 URL 编码的文本字符串。 您可以选择一个或多个表单元素(如输入和/或文本区),或表单元素本身。 序列化的值可在生成 AJAX 请求时, 用于 URL 查询字符串中。 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>菜鸟教程(runoob.com)</title> <script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"> </script> <script> $(document).ready(function () { $("button").click(function () { $("div").text($("form").serialize()); }); }); </script> </head> <body>
<form action=""> 第一个名称: <input type="text" name="FirstName" value="Mickey"/><br> 最后一个名称: <input type="text" name="LastName" value="Mouse"/><br> </form> <button>序列化表单值</button> <div></div>
</body> </html>
效果: |
序列化
● Django支持的序列化格式
Django支持的序列化格式包括json, xml和yaml, 我们只关注json的django序列化格式 |
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,主要用于传送数据。 |
● Django的serializers.serialize() & python的json.dumps()
对于Django的Queryset<Queryset [object,object,object]>, 不能使用python的json方法序列化,而要用到django的 serializers |
情况1: 使用serializers.serialize from django.core import serializers
ret = models.BookType.objects.all() data = serializers.serialize("json", ret)
#serialize()的参数是: # 序列化目标格式, # 序列化的QuerySet对象 (事实上,第二个参数可以是任何可迭代的Django Model实例,但它很多情况下就是一个QuerySet). |
情况2: 使用json.dumps()
|
拾陆 ● Django的表单系统: 主要分两种
一● 基于django.forms.Form
定义形式 from django import forms class FormName(forms.Form): field1 = forms.XXField(...) # model字段是field1 = models.XXField(...) field2 = forms.XXField(...)
表单字段的参数包括(不一定都有, 用逗号分隔参数) ① max_length这种字段固有的参数 ② 部件(widget)对象 ※ 字段参数负责"校验逻辑",而部件对象负责" 显示逻辑" #form.py from django import forms
class CommentForm(forms.Form): name = forms.CharField() url = forms.URLField() comment = forms.CharField(widget=forms.Textarea()) # Textarea后的括号可以省略 # Widget (部件)是Django 对HTML 输入元素的表示。(A widget is Django's representation of an HTML input element.) # 这里的 comment 会变成 Textarea,而不是 CharField
# 如果想让Widget 具有一些特殊的CSS 类, 可以这样设置: class CommentForm(forms.Form): name = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'})) url = forms.URLField() comment = forms.CharField(widget=forms.TextInput(attrs={'size': '40'})) |
title = forms.CharField(max_length=20, min_length=5, error_messages={'required': '标题不能为空', 'min_length': '标题最少为5个字符', 'max_length': '标题最多为20个字符'}, widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': '标题5-20个字符'})) |
●细节知识
Form 的对象具有一个is_valid() 方法,它为所有的字段运行验证的程序。 当调用这个方法时,如果所有的字段都包含合法的数据,它将: ① 返回True ② 将表单的数据放到cleaned_data属性中。 |
其它Form对象的API: http://www.lxway.com/496695522.htm |
二● 基于django.forms.ModelForm
※ ModelForm 能允许我们通过一个 Model, 直接创建一个和该Model的字段一一对应的表单,大大方便了表单操作: #models.py class ExamInfo(models.Model): field1 = models.XXField(...) # 表单字段是field1 = forms.XXField(...) field2 = models.XXField(...)
#form.py #定义ExamInfo的Form,Form的名字为模型名+Form from django.forms import ModelForm from .models import ExamInfo class ExamInfoForm(ModelForm): class Meta: model = ExamInfo fields = '__all__' # fields = ('field1','field2') #只显示model中指定的字段 |
● ※ form组件的主要功能
① 生成HTML标签 ② 验证用户数据(显示错误信息)----对用户提交的内容进行验证(from表单/Ajax) ③ 提交、保留上次提交的数据 ④ 初始化页面显示内容 |
● ※ 钩子(hook)(对于django来说)
局部钩子:校验单个字段,例如:用户名最短5个字符,最长12个字符;密码必须大于8位,验证码必须正确 全局钩子:校验多个字段,例如:密码和重复密码必须一致
※ 对于MFC编程来说,消息钩子分为局部钩子和全局钩子。 局部钩子将仅拦截某一进程的指定消息, 全局钩子将拦截系统中所有进程的指定消息。 |
拾柒 ● 跨站请求伪造(csrf/xsrf, Cross-site request forgery)
一 ● csrf定义
Django具有防止跨站请求伪造的功能,有全局和局部之分 --全局防止跨站请求伪造通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成 --局部防止跨站请求伪造通过@csrf_protect和@csrf_exempt装饰器来实现 ※ from django.views.decorators.csrf import csrf_protect, csrf_exempt ※ @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。 ※ @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。 |
二 ● csrf案例
用户访问www.mybank.com网站, 登录并且未退出, 用户同时访问了一个黑客网站, 黑客网站发给客户的html代码中带有上面的代码(一段假装生成一个图片元素的html代码, 是get方式的数据传递), 因而访问了src对应的可实现转账的代码(此时cookie未失效), 因此, 一段服务端发给浏览器的csrf_token可用来验证某段代码是用户的浏览器发送的代码, 而不是其它服务器发送的. |
三 ● csrf的应用
※ 详见: https://www.cnblogs.com/zhaof/p/6281482.html
1 ● 普通表单
|
这样当你查看页面源码的时候,可以看到form中有一个input是隐藏的 总结原理:当用户访问login页面的时候,会生成一个csrf的随机字符串,并且cookie中也存放了这个随机字符串(如下图),当用户再次提交数据的时候会带着这个随机字符串提交,如果没有这个随机字符串则无法提交成功 |
2 ● Ajax
对于传统的form,可以通过表单的方式将token再次(体会这个再次)发送到服务端,而对于ajax的话,使用如下方式。 |
1, csrf在ajax提交的时候是通过请求头(headers)传递的给后台的 2, csrf在前端的key为:X-CSRFtoken,到后端的时候django会自动添加HTTP_,并且最后为HTTP_X_CSRFtoken 3, csrf在form中提交的时需要在前端form中添加{%csrftoken%} |
|
|
拾捌 ● WSGI
一 ● WSGI定义
※ CGI(Common Gateway Interface)是通用网关接口,而WSGI就是Python的CGI包装,相对于Fastcgi是PHP的CGI包装, 它规定了Web服务器调用其他可执行程序(CGI程序)的接口协议标准。 |
(1) WSGI(Web Server Gateway Interface, Web服务器网关接口)是一种规范, 是将Python服务器端程序连接到Web服务器的通用协议,它实现了Web服务器和Web应用程序之间的解耦(decoupling)。
(2) WSGI接口规范的目的就是规范Web服务器与Web应用之间的交互,在协议之间进行转换(WSGI就是Web就是一个网关(Gateway),而网关的作用就是在协议之间进行转换。)
(3) WSGI将Web组件分成三类:Web服务器(WSGI Server)、Web中间件(WSGI Middleware)与Web应用程序(WSGI Application)。 --服务器:指的是实现了调用应用(call application)的部分。 --中间件:处于服务器和应用两侧,起粘合作用,具体包括:请求处理、environ, 即环境变量的处理。 --应用:指的是可以被调用的一个对象,一般指的是包含一个__call__方法(实例可以当作函数一般调用)的对象。
python标准库提供的独立WSGI服务器(WSGI server)称为wsgiref(模块)。 |
二 ● 注意
※ environ是Python内置的dict对象,它是系统的环境变量; ※ 通过import os; os.environ获取所有的环境变量; ※ 查看环境变量: os.environ.get('path')可以获取path这个环境变量被赋值的路径 ※ 设置环境变量: os.environ["PATH"] = os.environ["PATH"]+';' + "要增加的路径" |
三 ● WSGI的角色
WSGI的接口分为两个: 一个是它与Web服务器的接口,另一个是它与服务器端程序的接口。 ① WSGI Server与Web服务器的接口包括uwsgi、fast cgi等 (我们无须详细学习) ② 服务器端的开发者需要关注的是WSGI与服务器端程序的接口。 |
※ Django、CherryPy 都自带符合WSGI规范的 WSGI server, ※ 而有些 WSGI 下的框架比如 pylons、bfg 等, 自己不实现 WSGI server, 而是使用 paste 作为 WSGI server, paste 是流行的 WSGI server, 带有很多中间件。 |
四 ● Django内置的服务器
Django 内部自带了一个方便本地测试的小服务器, 所以在刚开始学习 Django 的时候并不需搭建 apache 或者 nginx 服务器.
Django 自带的服务器基于 python wsgiref 模块实现的, 其百分之七八十的代码都是 wsgiref 中的代码, 只重写了一部分. 具体来说, Django 内置服务器基于 django.core.servers 和 django.core.handlers这两个类共同实现. |
拾玖 ● 中间件(MIDDLEWARE )
一 ● 中间件的介绍
在django中,中间件其实就是一个类; 在settings.py中,MIDDLEWARE 列表的每一个元素就是一个中间件:
在http请求到达视图函数之前和视图函数return之后,Django会根据自己的规则在合适的时机执行中间件中相应的方法。
注意: 如果在其中一个中间件里 request方法里 return了值,就会执行当前中间件的response方法,返回给用户然后报错, 并且不会再执行下一个中间件。
Django会先按顺序执行各个中间件的request方法, 然后执行视图函数, 然后反序执行各个中间件的response方法.例如: |
二 ● 自定义中间件的步骤
|
|
结果: 为啥报错了呢?
因为自定义的中间件response方法没有return结果交给下一个中间件,导致http请求中断了!!!
注意: 自定义的中间件request 方法不要return结果, 否则, 中间件不再会往下执行,导致 http请求到达不了视图层.
|
三 ● 中间件中可以定义5个方法,分别是:
process_request(self,request) process_view(self, request, callback, callback_args, callback_kwargs) process_template_response(self,request,response) process_exception(self, request, exception) process_response(self, request, response |
有关自定义中间件, 参见: https://www.cnblogs.com/huchong/p/7819296.html |
贰拾 ● Django的信号
一 ● 信号的定义
Django中提供了"信号调度",用于在框架执行操作时解耦. 一些动作发生的时候,系统会根据信号定义的函数执行相应的操作. (例如下面的: 创建数据库记录时, 触发pre_save和post_save信号) 对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,系统会自动触发注册函数 |
二 ● 信号的案例
※ 创建数据库记录时, 触发pre_save和post_save信号 |
# models.py
|
#
|
#
|
#
|
有关自定义信号
|
贰拾壹 ● Django的缓存
一 ● 缓存的定义
缓存,缓存将一个某个views的返回值保存至内存或者memcache中,之后再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿到,并返回。 |
Django settings 中 cache 默认为 { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', } } 也就是默认利用本地的内存来当缓存,速度很快,当然可能出来内存不够用的情况。 |
二 ● Django中提供缓存方式
※ 下面的缓存方式都需要在setting.py里面配置: - 开发调试 - 本地内存(默认的缓存方式) - 文件 - 数据库 - Memcache缓存(python-memcached模块)----memcache是一套分布式的高速缓存系统 - Memcache缓存(pylibmc模块) - Redis缓存 |
详见: https://code.ziqiangxuetang.com/django/django-cache.html http://www.cnblogs.com/haiyan123/p/8424231.html |
贰拾贰 ● admin
django amdin是django提供的一个后台管理页面,改管理页面提供完善的html和css,使得你在通过Model创建完数据库表之后,就可以对数据进行增删改查. |
我们学习和使用更加完善的xadmin, 下面只介绍admin的简单用法. |
● admin的一般使用步骤
① 在项目名/项目名/urls.py配置url url(r'^admin/', include(admin.site.urls))
② 注册medel类到admin: 在应用名/admin.py里面把我们当前应用models.py里面的User 这个model注册进去,如下。 from django.contrib import admin from .models import User
admin.site.register(User) # 通过admin.site.register()函数逐个声明要管理的模型类. # 再如: 假设有Book, MyAdmin, Publish, Author五个模型类: admin.site.register(Book,MyAdmin) # 将Author模块和管理类绑定在一起,注册到后台管理 admin.site.register(Publish) admin.site.register(Author)
通过python manage.py runserver命令启动项目,然后http://127.0.0.1:8000/admin访问,会自动跳转到它的主页,如图所示:
③ 通过"python manage.py createsuperuser"命令创建超级用户,例如: python manage.py createsuperuser Username: admin Email address: Password: Password (again): Superuser created successfully.
假如我创建了一个用户名:admin 密码:admin123的用户,我们就可以登录进django admin后台管理系统了,登录成功如下所示,我们可以通过右侧的 "add" 添加用户: 我们操作admin和我们操作数据库是一样的,例如上面的Users对应的就是sqlite数据库中的user表,也就是说,如果要求不高的话后台都不需要我们开发了! |
贰拾叁 ● 设置404页面和500页面
1, 在blog/templates/user下面添加一个404.html和一个500.html页面,代码任意,
2, 配置setting.py文件,如下: ※ 当DEBUG=True的时候, django的runserver是自动使用StaticFilesHandler来serve 静态文件的, 当DEBUG=False的时候, django就不处理静态文件, 交由其它的静态服务器来处理.
3, 在主urls.py(settings.py文件下面)添加如下配置: 前面的代码是固定的,后面代码的意思是在blog模块下的views.py中处理这两个404和500错误。
4, 在views.py中添加page_not_found和page_error这两个方法,用于页面跳转,如下:
|
贰拾肆 ● 富文本编辑器
常用富文本编辑器 |
Kindeditor 参考: http://www.cnblogs.com/wupeiqi/articles/6307554.html
DjangoUeditor3 参考: http://www.cnblogs.com/adc8868/p/7580705.html
Tinymce 参考: http://blog.csdn.net/u010505059/article/details/78650742 |
贰拾伍 ● REST & RESTful API
REST, Representational State Transfer,"表现层状态转化", 全称是 Resource Representational State Transfer, 即"资源在网络中以某种表现形式进行状态转移" ※ Resource:资源,即数据(网络的核心,例如newsfeed,friends等); Representational:某种表现形式,例如JSON,XML,JPEG等; State Transfer:状态变化, 通过GET,POST等HTTP动词实现。 |
RESTful API: 符合REST架构设计的API, HTTP协议就是属于REST架构的设计模式, 例如: 无状态,请求-响应机制. RESTful API要求增删查改都是一个地址,具体靠HTTP请求头部信息判断, HTTP请求头包括Content-Type等信息. |
※ REST是所有Web应用都应该遵守的架构设计指导原则。当然,REST并不是法律,违反了REST的指导原则,仍然能够实现应用的功能。但是违反了REST的指导原则,会付出很多代价,特别是对于大流量的网站而言 |