前男友突然进我空间想进他空间,发现进不了。说他居对我设置了权限,顺便截了个图。过去给他看他这么回

2013年10月 其他开发语言大版内专家分月排行榜第二2012年2月 其他开发语言大版内专家分月排行榜第二
2013年11月 其他开发语言大版内专家分月排行榜第三2012年4月 其他开发语言大版内专家分月排行榜第三2011年6月 其他开发语言大版内专家分月排行榜第三
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。浏览器不支持嵌入式框架,或被配置为不显示嵌入式框架。python Flask JQuery使用说明
最近由于某种原因再次学习Flask框架,借助博客整理相关内容。Flask框架和Apache+存在少许不同,Flask框架中JS和文件存放于一个相对固定的位置。一般情况下,位于static文件夹下(见图1 目录结构)。本文结合一个非常简单的加法例子试图说明Flask框架中JQuery和Ajax的用法。
这个例子将运行在树莓派中,请注意windows平台和linux平台也可以运行该示例,python具有良好的跨平台性能。
【代码仓库】
代码仓库位于Bitbucket,可下载zip包或通过TortoiseHg克隆代码。
【相关博文】
【1】python 扩展库安装 使用第三方镜像源
【2】python Flask 学前班
【3】前端学习——HTML4和HTML5设定页面语言字符集
【4】前端学习——JQuery Ajax使用经验
1.引入JQuery
jquery.js文件需要存放于static文件夹中,在前端的代码中还需要指定该js文件的路径,这些路径均为“相对路径”。强烈建议把所有的文件都保存为UTF8格式,以免产生中文乱码现象。
【目录结构】
图1 目录结构
【static目录】——jqury.js
【templates目录】——main.html
【flask-jquery.py】
2.简单示例
【1】前端部分
【templates目录】——main.html
&script src="{{url_for('static', filename='jquery.js')}}"&&/script&
&script type=text/javascript&
var $SCRIPT_ROOT = {{request.script_root|tojson|safe}};
&script type=text/javascript&
$(function() {
function submit_form(e) {
$.getJSON($SCRIPT_ROOT + '/add', {
a: $('input[name="a"]').val(),
b: $('input[name="b"]').val(),
now: new Date().getTime()
function(data) {
$('#result').text(data.result);
// 绑定click事件
$('#calculate').bind('click', submit_form);
【简要说明】
【1】 网页编码为UTF8,请注意网页文件也要保存为UTF8格式
【2】&script src="{{url_for('static', filename='jquery.js')}}"&&/script&
载入位于static文件夹中的jquery.js文件
【3】var $SCRIPT_ROOT = {{request.script_root|tojson|safe}};
抱歉,暂未理解其含义
【4】now: new Date().getTime() 防止缓存的一种小技巧。
【2】后端部分
【flask-jquery.py】
# -*- coding: utf-8 -*-
from flask import Flask, jsonify, render_template, request
app = Flask(__name__)
@app.route("/")
def index():
return render_template("main.html")
@app.route('/add')
def add_numbers():
a = request.args.get('a', 0, type=int)
b = request.args.get('b', 0, type=int)
return jsonify(result = a + b)
if __name__=="__main__":
app.run(host = "0.0.0.0",port = 8080, debug = True)
【简要说明】
【1】request.args.get('a', 0, type=int) 前端通过GET方法提交,在URI提取参数a和参数b。中间的一个0为a和b的默认值,当函数执行失败时,a或b就只能等于0了。
【2】app.run(host = "0.0.0.0",port = 8080, debug = True)。所有IP地址均可以访问,端口号为8080,而不是默认的80端口。
【3】运行于树莓派中
把图1所示的文件夹FTP传输到树莓派中,执行flask-jquery.py即可
python flask-jquery.py
图2 前端页面
图3 后台调试输出
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'涉及到的插件和包有Flask-WTF,WTForms。内容有表单的创建使用流程,一些最佳实践,还有在页面显示提示消息的简单方式,配合Flask内置的 flash()。
Flask的requset对象包含了client端发送过来的所有请求,在request.form中就有POST方法提交过来的表单数据。直接使用这些数据可以搞定表单的操作,不过不方便,于是有了Flask-WTF这个插件,它将WTForms这个包嵌入Flask里,简化Flask下的使用。pip安装会把插件的以来也安装进来:
pip install flask–wtf
WTForms应该也同时被安装了。
跨站请求伪造(Cross-Site Request Forgery,CSRF) 保护
CSRF的原理不具体讲了,很简单,感兴趣直接网上搜即可。
Flask-WTF默认提供对CSRF的保护。应用里需要设置一个加密用的key,Flask-WTF利用这个key生成一个加密的记号来验证request带过来的表单数据。看看实例:
app = Flask(__name__)
app.config[‘SECRET_KEY’] = ‘’
app.config 是应用保存配置的一个字典。可以直接在字典里增加配置。SECRET_KEY这个配置变量被Flask和一些第三方插件使用,对不同的应用配置不同的值增加点可靠性。
另外,这个值最好放到环境变量里,直接写到代码里不太好。
使用Flask-WTF的时候,每一个表单都是类的形式,这个类需要继承自Form。这个类里定义一些代表表单各类域的对象,每个对象可以有多个验证器(validators)。验证器可以确保用户的输入是有效的。
from flask.ext.wtf import Form
from wtforms import StringField, SubmitField
from wtforms.validators import Required
class NameForm(Form):
name = StringField(‘What is your name?’, validators=[Required()])
submit = SubmitField(‘Submit’)
表单中的域在类中都定义成类变量。上例中,NameForm类里有文本域name和提交按钮submit两个。StringField代表有type="text"属性的&input&元素。SubmitField代表有type="submit"属性的&input&元素。构造器的第一个参数是后续渲染表单时候用到的标签(label)。
下例是一个带有文本域和提交按钮的表单例子:
from flask_wtf import Form
from wtforms import StringField, BooleanField, PasswordField,SubmitField
from wtforms.validators import DataRequired
class LoginForm(Form):
openid = StringField(‘openid’, validators=[DataRequired()])
remember_me = BooleanField(‘remember_me’, default = False)
password = PasswordField(‘password’,validators=[DataRequired()])
submit = SubmitField(‘submit’)
表单中的域在类中都定义成类变量。上例中,LoginForm类里有字符串域openid,复选框remember_me, 密码域password,提交按钮submit。分别代表小面信息:
&input id=“openid” name=“openid” type=“text” value=“”&
&input id=“remember_me” name=“remember_me” type=“checkbox” value=“y”&
&input id=“password” name=“password” type=“password” value=“”&
&input id=“submit” name=“submit” type=“submit” value=“submit”&
构造器的第一个参数是后续渲染表单时候用到的标签(label)。
在StringField里的validators参数定义了一些验证器,这些验证器会在用户提交数据前检查数据是否有效。Required验证器确保提交的内容不能为空。
WTForms提供的各种HTML域:
StringField
TextAreaField
PasswordField
密码类文本
HiddenField
接收给定格式的 datetime.datevalue 的文本
DateTimeField
接收给定格式的 datetime.datetimevalue 的文本T
IntegerField
接收整数的文本
DecimalField
接收decimal.Decimal类型值的文本
FloatField
接收浮点类型值的文本
BooleanField
选是否的复选框
RadioField
包含多个互斥选项的复选框
SelectField
SelectMultipleField
可多选的下拉菜单
SubmitField
讲一个表单作为域放入另一个表单里
一组给定类型的域
WTForms提供的各种验证器:
Description
比较两个域的值,例如在要求输入两次密码的时候
按字符串的长度验证
NumberRange
输入数字需在某范围内
允许不填,不填的时候就忽略其他验证器
通过一个正则表达式验证
属于一组可能值中的一个
不属于一组可能值中的任何一个
表单的各类域在模板中渲染时表现为可调用的对象。假设将一个NameForm的实例name作为参数传入模板。
&form method=“POST”&
{{ form.name.label }} {{ form.name() }}
{{ form.submit() }}
这样渲染出来的页面不美观,可以尝试改进下,在调用里传入一些参数,这些参数都会被转化为这个域的属性。然后你可以用CSS自己搞定美化问题:
&form method=“POST”&
{{ form.name.label }} {{ form.name(id=‘my-text-field’) }}
{{ form.submit() }}
上述方式显然很累,之前加入了Bootstrap的支持,Flask-Bootstrap插件其实也对Flask-WTF创建的表单有高层接口的支持,可以用Bootstrap来修饰一下。然后表单的模板就可以简单写成:
{% import “bootstrap/wtf.html” as wtf %}
{{ wtf.quick_form(form) }}
从其他模板import个函数进来之前提到过,wtf.quick_form函数接受一个Flask-WTF的表单,然后用Bootstrap默认的样式渲染。
现在,首页index.html已经改为:
{% extends “base.html” %}
{% import “bootstrap/wtf.html” as wtf %}
{% block title %}Flasky{% endblock %}
{% block page_content %}
&div class=“page-header”&
&h1&Hello, {% if name %}{{ name }}{% else %}Stranger{% endif %}!&/h1&
{{ wtf.quick_form(form) }}
{% endblock %}
这里还用了一个if else结构,如果传入了name,就显示传入的值,否则就显示Stranger。
表单的各类域在模板中渲染时表现为可调用的对象。假设将一个LoginForm的实例openid作为参数传入模板。
&form action=“” method=“post” name=“login”&
{{form.hidden_tag()}}
{{ form.openid.label }}
{{form.openid(size=80)}}
{% for error in form.openid.errors %}
&span style=“color:”&{{ error }}&/span&
{% endfor %}&br&
{{ form.password }}
{% for error in form.password.errors %}
&span style=“color:”&{{ error }}&/span&
{% endfor%}
{{form.remember_me}} Remeber Me&/p&
{{ form.submit(value=‘登录’) }}
视图函数中的表单处理
修改hello.py,在index()里处理表单数据。
@app.route(‘/’, methods=[‘GET’, ‘POST’])
def index():
name = None
form = NameForm()
if form.validate_on_submit():
name = form.name.data
form.name.data = ”
return render_template(‘index.html’, form=form, name=name)
可以注意到,在app.route装饰器增加了methods参数,这里是把index()注册为GET和POST请求的处理者。如果不提供methods这个参数,试图函数默认只处理GET请求。
这里对index()增加视图函数对POST请求的支持是必须的,因为用户的提交操作使用POST请求更方便处理。使用GET请求来提交表单也可以,但是GET请求的数据都是附加在URL后面作为请求字符串,在浏览器的地址栏可以看到。由此,以及一些其他原因,表单的提交通常都是用POST请求完成的。
继续看改动后的代码,form.validate_on_submit()这个方法,只在用户提交了数据并且数据通过验证器的检查之后,才返回True,其他时候都返回False。用这个方法判断是否对模板进行处理。
看下一般处理流程。用户第一次访问这个应用,使用的是GET请求,不带数据,form.validate_on_submit()这个方法返回False,return就返回一个空白的表单,name值是None。
用户提交了表单后,sercer收到携带数据的POST请求,form.validate_on_submit()这个方法会启动之前设置的Required()验证器,这里name不为空就通过验证,form.validate_on_submit()返回True。然后提取出表单数据保存下来,把表单数据清空。再把name和表单传入render_template(),重新渲染的模板就有了变化。
@app.route(‘/login’, methods=[‘GET’, ‘POST’])
def login():
form = LoginForm()
print form.openid
print form.remember_me
print form.password
print form.submit
if form.validate_on_submit():
flash(‘Login requested for OpenID=”‘ + form.openid.data + ‘”, remember_me=’ + str(form.remember_me.data) + ‘ password: ‘
return redirect(‘/index’)
return render_template(‘login.html’, title = ‘Sign In’, form = form)
分享到: ()

我要回帖

更多关于 前男友突然进我空间 的文章

 

随机推荐