目录
第01章 安装
第02章 程序的基本结构
第03章 模版
第04章 Web表单
第05章 数据库
第06章 电子邮件
第07章 大型程序的结构
第08章 用户认证
第09章 用户角色
第15章 测试
第16章 性能
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World!
'
@app.route('/user/')
def user(name):
return 'Hello, %s!
' % name
if __name__ == '__main__':
app.run(debug=True)
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World!
'
@app.route('/user/')
def user(name):
return 'Hello,%s!
' % name
if __name__ == '__main__':
app.run(debug=True)
变量名 | 上下文 | 说明 |
---|---|---|
current_app | 程序上下文 | 当前激活程序的程序实例 |
g | 程序上下文 | 处理请求时用作临时存储对象,每次请求都会重设这个变量 |
request | 请求上下文 | 请求对象,封装了客户端发出的HTTP请求中的内容 |
session | 请求上下文 | 用户会话,用于存储请求之间需要“记住”的值的词典 |
from flask import request
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
user_agent = request.headers.get('User-Agent')
return 'Your browser is %s
' % user_agent
if __name__ == '__main__':
app.run(debug=True)
>>> from hello import app
>>> from flask import current_app
>>> current_app.name #此时使用会出错
>>> app_ctx = app.app_context()
>>> app_ctx.push()
>>> current_app.name #'hello'
>>> app_ctx.pop()
@app.route('/')
def index():
return 'Bad Request
', 400
from flask import make_response
@app.route('/')
def index():
response = make_response('This document carries a cookie!
')
response.set_cookie('answer', '42')
return response
from flask import redirect
@app.route('/')
def index():
return redirect('http://www.example.com')
from flask import abort
@app.route('/user/')
def get_user(id):
user = load_user(id)
if not user:
abort(404)
return 'Hello, %s
' % user.name
from flask import Flask
from flask_script import Manager #此处和书中不同,是因为版本修改了,名字也不同了
app = Flask(__name__)
manager = Manager(app)
@app.route('/')
def index():
return 'Hello World!
'
@app.route('/user/')
def user(name):
return 'Hello,%s!
' % name
if __name__ == '__main__':
manager.run()
from flask import Flask, render_template
@app.route('/')
def index():
return render_template('index.html')
@app.route('/user/')
def user(name):
return render_template('user.html', name=name)
Hello, {{ name }}!
A value from a dictionary: {{ mydict['key'] }}.
A value from a list: {{ mylist[3] }}.
A value from a list, with a variable index: {{ mylist[myintvar] }}.
A value from an object's method: {{ myobj.somemethod() }}.
Hello, {{ name|capitalize }}
过滤器名 | 说明 |
---|---|
safe | 渲染值时不转义 |
capitalize | 把值的首字母转换为大写,其他字母转换为小写 |
lower | 把值转为小写形式 |
upper | 把值转换成大写形式 |
title | 把值中每个单词的首字母都转换成大写 |
trim | 把值的首尾空格去掉 |
striptags | 渲染之前把值中所以的HTML标签删掉 |
{% if user %}
Hello, {{ user }}!
{% else %}
Hello, Stranger!
{% endif %}
{% for comment in comments %}
- {{ comment }}
{% endfor %}
{% macro render_comment(comment) %}
{{ comment }}
{% endmacro %}
{% for comment in comments %}
{{ render_comment(comment) }}
{% endfor %}
{% import 'macros.html' as macros %}
{% for comment in comments %}
{{ macros.render_comment(comment) }}
{% endfor %}
{% block head %}
{% block title %}{% endblock %} - My Application
{% endblock %}
{% block body %}
{% endblock %}
②上面基模版的衍生模版:extends 指令声明这个模板衍生自base.html。在extends 指令之后,基模板中的3 个块被重新定义,模板引擎会将其插入适当的位置。注意新定义的head 块,在基模板中其内容不是空的,所以使用super() 获取原来的内容。{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block body %}
Hello, World!
{% endblock %}
from flask_bootstrap import Bootstrap
# ...
bootstrap = Bootstrap(app)
{% extends "bootstrap/base.html" %}
{% block title %}Flasky{% endblock %}
{% block navbar %}
Hello, {{ name }}!
{% endblock %}
{% endblock %}
{% block content %}
@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
@app.errorhandler(500)
def internal_server_error(e):
return render_template('500.html'), 500
app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'
from flask_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')
from flask import Flask, request, render_template
from flask_wtf import Form
from wtforms import StringField, SubmitField
from wtforms.validators import Required
from flask_bootstrap import Bootstrap
app = Flask(__name__)
bootstrap = Bootstrap(app)
class NameForm(Form):
name = StringField('What is your name?', validators=[Required()])
submit = SubmitField('Submit')
@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)
if __name__ == '__main__':
app.run(debug=True)
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Flasky{% endblock %}
{% block page_content %}
Hello, {% if name %}{{ name }}{% else %}Stranger{% endif %}!
{{ wtf.quick_form(form) }}
{% endblock %}
{% extends "bootstrap/base.html" %}
{% block title %}Flasky{% endblock %}
{% block navbar %}
{% block page_content %}{% endblock %}
{% endblock %}
{% endblock %}
{% block content %}
from flask import Flask, render_template, session, redirect, url_for
@app.route('/', methods=['GET', 'POST'])
def index():
form = NameForm()
if form.validate_on_submit():
session['name'] = form.name.data
return redirect(url_for('index'))
return render_template('index.html', form=form, name=session.get('name'))
from flask_sqlalchemy import SQLAlchemy
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] =\
'sqlite:///' + os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
db = SQLAlchemy(app)
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
def __repr__(self):
return '' % self.name
users = db.relationship('User', backref='role')
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True, index=True)
def __repr__(self):
return '' % self.username
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
@app.route('/', methods=['GET', 'POST'])
def index():
form = NameForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.name.data).first()
if user is None:
user = User(username = form.name.data)
db.session.add(user)
session['known'] = False
else:
session['known'] = True
session['name'] = form.name.data
form.name.data = ''
return redirect(url_for('index'))
return render_template('index.html',
form = form, name = session.get('name'),
known = session.get('known', False))
配 | 置默认值 | 说明 |
---|---|---|
MAIL_SERVER | localhost | 电子邮件服务器的主机名或IP 地址 |
MAIL_PORT | 25 | 电子邮件服务器的端口 |
MAIL_USE_TLS | False | 启用传输层安全(Transport Layer Security)协议 |
MAIL_USE_SSL | False | 启用安全套接层(Secure Sockets Layer)协议 |
MAIL_USERNAME | None | 邮件账户的用户名 |
MAIL_PASSWORD | None | 邮件账户的密码 |
from flask_mail import Mail
import os
# ...
mail = Mail(app)
# ...
#设置邮件发送者
app.config['MAIL_SERVER'] = 'smtp.googlemail.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME')
app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD')
#发送一封邮件
msg = Message('test subject', sender='[email protected]',recipients=['[email protected]'])
msg.body = 'text body'
msg.html = 'HTML body'
with app.app_context():
mail.send(msg)
from flask_mail import Message
app.config['FLASKY_MAIL_SUBJECT_PREFIX'] = '[Flasky]'
app.config['FLASKY_MAIL_SENDER'] = 'Flasky Admin '
def send_email(to, subject, template, **kwargs):
msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + subject,sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to])
msg.body = render_template(template + '.txt', **kwargs)
msg.html = render_template(template + '.html', **kwargs)
mail.send(msg)
|-flasky
|-app/
|-templates/
|-static/
|-main/
|-__init__.py
|-errors.py
|-forms.py
|-views.py
|-__init__.py
|-email.py
|-models.py
|-migrations/
|-tests/
|-__init__.py
|-test*.py
|-venv/
|-requirements.txt
|-config.py
|-manage.py
方法 | 说明 |
---|---|
is_authenticated() | 如果用户已经登录,必须返回True,否则返回False |
is_active() | 如果允许用户登录,必须返回True,否则返回False。如果要禁用账户,可以返回False |
is_anonymous() | 对普通用户必须返回False |
get_id() | 必须返回用户的唯一标识符,使用Unicode 编码字符串 |
from flask.ext.login import UserMixin
class User(UserMixin, db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key = True)
email = db.Column(db.String(64), unique=True, index=True)
username = db.Column(db.String(64), unique=True, index=True)
password_hash = db.Column(db.String(128))
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
from flask.ext.login import LoginManager
login_manager = LoginManager()
login_manager.session_protection = 'strong'
login_manager.login_view = 'auth.login'
def create_app(config_name):
# ...
login_manager.init_app(app)
# ...
from flask_wtf import Form
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import Required, Length, Email, Regexp, EqualTo
from wtforms import ValidationError
from ..models import User
class RegistrationForm(Form):
email = StringField('Email', validators=[Required(), Length(1, 64),
Email()])
username = StringField('Username', validators=[
Required(), Length(1, 64), Regexp('^[A-Za-z][A-Za-z0-9_.]*$', 0,
'Usernames must have only letters, '
'numbers, dots or underscores')])
password = PasswordField('Password', validators=[
Required(), EqualTo('password2', message='Passwords must match.')])
password2 = PasswordField('Confirm password', validators=[Required()])
submit = SubmitField('Register')
def validate_email(self, field):
if User.query.filter_by(email=field.data).first():
raise ValidationError('Email already registered.')
def validate_username(self, field):
if User.query.filter_by(username=field.data).first():
raise ValidationError('Username already in use.')