文档:
flask:
http://docs.jinkan.org/docs/flask/quickstart.html#redirects-and-errors
jinja2
http://docs.jinkan.org/docs/jinja2/
flask-script:
http://flask-script.readthedocs.io/en/latest/
flask-sqlalchemy:
http://www.pythondoc.com/flask-sqlalchemy/quickstart.html
一:基本内容
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route('/index/')
def index():
return render_template('index.html',title='<h1>这是第一个测试</h1>')
@app.route('/about/')
def about():
return render_template('about.html',data='about页面')
if __name__ == '__main__':
app.run(debug=True)
app = Flask(name) 生成一个Flask的实例
app.route('/') 指定路由名称
render_template('index.html',title='
这是第一个测试
') 向html返回一个服务器端回发的内容对于html页面端:
{{ title|safe }} 输出title的值,并且标记为安全类型
<a href="{{ url_for('about') }}">about页面</a> 使用url_for 逆向生成路由地址,about为方法名称
引用静态文件:
<link rel="stylesheet" href="{{url_for('static',filename="")}}">
示例:
<link rel="stylesheet" href="{{ url_for('static',filename='css/main.css') }}"/>
二:路由
动态路由:
@app.route('/user/<int:use_id>/')
def user1(use_id):
return "userid %d"%use_id
路由的三种形式:
@app.route('/user/')
@app.route('/user/<username>')
@app.route('/user/<int:use_id>/')
四:参数的获取:
POST:
username=request.form.get('username')
password=request.form.get('password')
GET:
tag=request.args.get('tags')
五:cookies的设置:
@app.route('/setcookies/')
def setCookies():
if request.method=='GET':
response= make_response(render_template('userlogin.html'))
response.set_cookie('username','hello')
return response
六:读取cookies:
@app.route('/getCookies/')
def getCookies():
if request.method=='GET':
cookies=request.cookies.get('username')
print(cookies)
return Response('ok')
七:设置出错页面:
@app.errorhandler(404)
def page_not_found(error):
return render_template('404.html'),404
八:使用scripts插件:
版本: Flask-Script==2.0.6
pip install Flask-Script==2.0.6
使用Manager替换app
from flask.ext.script import Manager
app = Flask(__name__)
managerinstance=Manager(app)
app.route('/test/')
def test():
pass
if __name__ == '__main__':
managerinstance.run()
启动应用 :
python flaskDemo.py runserver
九:模版:
官方文档:
http://jinja.pocoo.org/docs/2.10/templates/#variables
取值{{}}
语句块{%%}:
{%for item in data%}
{%endfor%}
过滤器:
{{data|safe}}
赋值:
{% set links=[
{'label':'Home','href':url_for('index')},
{'label':'Home','href':url_for('index')},
] %}
上述语句即为变量links赋值
在页面中显示变量的值为{{links}}
限制模版中变量的作用域
将变量放置在with语句块中,变量将只在当前的作用范围内生效,如下所示:
{% with %}
{% set links=[
{'label':'Home','href':url_for('index')},
{'label':'Home','href':url_for('index')},
] %}
{% endwith %}
此时如果在with块外部调用该变量,将无法显示该变量的值
如果要在页面上生成以上相应的菜单标签,可以按以下代码操作,在循环中依次取出对应的值
<nav>
{% for link in links %}
<a href="{{ link.href }}">{{ link.label }}</a>
{% endfor %}
</nav>
菜单生成的改进版:
{% set links_1=[
('Home',url_for('index')),
('about',url_for('about')),
] %}
<nav>
{% for label,link in links_1 %}
{% if not loop.first %}|{% endif %}
<a href="{{ link }}">{{ label }}</a>
{% endfor %}
</nav>
模版继承:
1:创建block块进行占位
{%block head%}{%endblock%}
{%block content%}{%endblock%}
block为关键字
head content为占位名称,名称可随意,但不可重复
2:页面继承
{%extends 'base.html'%}
3:在模版中对部分内容的重复调用:
@app.route('/test/')
def testExtTemplate():
return render_template('templatePages.html',data='测试测试',title='测试一下')
{% extends '_layout.html' %}
{% block title %}
{{ title }}
{% endblock %}
{% block content %}
<p>
{{ self.title() }}
</p>
{% endblock %}
在以上代码即实现,对title的重复调用
在conent中如果要重新显示title的值时,可以使用{{self.title()}},在这里tile是调用方法,如果是调用title的话将会返回一下地址
如果在页面的模版页面中需要在显示上级模板的基础上显示自定义的内容,如:
在_layout.html模版文件中有以下定义:
{% block foot %}
这是尾部
{% endblock %}
在子页面中重写了该部分内容,该部分内容将被覆盖,如子页面代码如下所示:
{% block foot %}
<hr>
{% endblock %}
如果,此时仅仅是想添加一些内容,并且保留父级内容,可按如下代码所示:
{% block foot %}
<hr>
{{ super() }}
{% endblock %}
以上代码将添加一个水平线后同时调用父级内容
包含其它页面:
如果需要在当前页面包含进来其它的页面可以使用如下语法:
{% include 'index.html' %}
页面中内容的重用:
如果对于页面中的内容,如表单标签或其它内容进行重用可以按以下方式进行宏定义
如,需要对一批的input标签进行重用的时候,而不希望去重复的写input标签,可以按以下方式来操作
宏定义:
{% macro input(name,value='',type='text',size=20)%}
<input type="{{ type }}"
name="{{ name }}"
value="{{ value }}"
size="{{ size }}"/>
{% endmacro %}
调用:
username: {{ input("username") }}
password:{{ input(name="username",type="password") }}
如果定义了大量的宏,可以把宏定义放到一统一的文件中,如
新建立一个macro.html,将以上代码复制到该文件中,如下所示:
{% macro input(name,value='',type='text',size=20)%}
<input type="{{ type }}"
name="{{ name }}"
value="{{ value }}"
size="{{ size }}"/>
{% endmacro %}
在需要使用宏的html文件中,将该宏文件导入
{% import 'macro.html' as ui %}
同时对于调用代码改变为以下代码
username: {{ ui.input("username") }}
password:{{ ui.input(name="username",type="password") }}
十:在flask中使用bootstrap插件
1:安装 flask-bootstrap
pip install flask-bootstrap
2:页面继承:
{% extends 'bootstrap/base.html' %}
对于flask-bootstrap安装后,在源码的template目录的bootstrap文件夹中中将生成几个html文件分别为:
base.html
fixes.html
google.html
pagination.html
utils.html
wtf.html
将主要使用以上几个html文件作为flask项目中的模板页面
使用案例:
在py文件中:
from flask_bootstrap import Bootstrap
Bootstrap(app)
如果不在py文件中导入并实例化,那么在页面中继承bootstrap的页面时将直接报错
{% extends 'bootstrap/base.html' %}
<html>
<head>
<title>Title</title>
</head>
<body>
{% block content %}
{% set links_1=[
('Home',url_for('index')),
('about',url_for('about')),
] %}
<div class="navbar navbar-inverse ">
<nav class="nav">
{% for label,link in links_1 %}
{% if not loop.first %}|{% endif %}
<a href="{{ link }}">{{ label }}</a>
{% endfor %}
</nav>
</div>
{% endblock %}
</body>
</html>
十一:对于生成导航菜单可以使用另外一个插件:flask-nav
安装flask-nav
pip3 install flask-nav
在py文件中导入:
from flask_nav import Nav
from flask_nav.elements import *
nav=Nav()
nav.register_element('top',Navbar('flask入门',
View('主页','index'),
View('关于','about')
))
nav.init_app(app)
在html文件中:
{% extends 'bootstrap/base.html' %}
{% block navbar %}
{{ nav.top.render() }} top为定义的名称
{% endblock %}
十二:表单
安装 :pip install flask-wtf
提供的所有的字段类型:
__all__ = (
'BooleanField',
'DecimalField',
'DateField',
'DateTimeField',
'FieldList',
'FloatField',
'FormField',
'IntegerField',
'RadioField',
'SelectField',
'SelectMultipleField',
'StringField',
)
表单的范例:
表单类:loginForm.py
from flask.ext.wtf import Form
from wtforms import StringField,PasswordField,SubmitField
from wtforms.validators import DataRequired
class Login_form(Form):
username=StringField(label='用户名',validators=[DataRequired()])
password=PasswordField(label='密码',validators=[DataRequired()])
submit=SubmitField(label='提交')
函数:
@app.route('/login/')
def login():
from loginForm import Login_form
form=Login_form()
return render_template('loginpage.html',form=form)
html文件:
<form method="post">
{{ form.username.label }}
{{ form.username() }}
{{ form.password.label }}
{{ form.password() }}
{{ form.submit() }}
</form>
以上代码会建立一个基础的表单,但是当访问login时会出现csrf的跨站请求伪造的错误,所以需要定义一个公钥并使用
如下所示,建立一个文件用于存放公钥,如config.py
SECRET_KEY='wo shi yi ge baobao a '
在代码代码中使用以上定义的公钥:
app.config.from_pyfile('config.py')
验证器支持的类型:
__all__ = (
'DataRequired', 'data_required', 'Email', 'email', 'EqualTo', 'equal_to',
'IPAddress', 'ip_address', 'InputRequired', 'input_required', 'Length',
'length', 'NumberRange', 'number_range', 'Optional', 'optional',
'Required', 'required', 'Regexp', 'regexp', 'URL', 'url', 'AnyOf',
'any_of', 'NoneOf', 'none_of', 'MacAddress', 'mac_address', 'UUID'
)
自动生成表单并应用 bootstrap样式:
{% extends 'bootstrap/base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block content %}
<div style=" 300px;" class="container">
{{ wtf.quick_form(form) }}
</div>
{% endblock %}
对于需要展现的一些消息,可以按如下方法展现:
from flask import Flask,render_template,request,redirect,
make_response,abort,Response,flash
@app.route('/login/')
def login():
from loginForm import Login_form
form=Login_form()
flash('欢迎登录系统') 在此写入消息
return render_template('loginpage.html',form=form)
在flask中导入flash模块
在html页面:
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
flask开发遇到 Must provide secret_key to use csrf解决办法
开发flask的时候,遇到了 Must provide secret_key to use csrf错误提醒。原来是没有设置secret_key 。在代码中加上
app.config['SECRET_KEY']='xxx'
SECRET_KEY最好不要写在代码中。
最好设置一个config.py文件,从中读取该内容
config.py
CSRF_ENABLED = True
SECRET_KEY = 'you-will-never-guess'
app.py
app.config.from_object('config')
这样就可以防止csrf了