使用虚拟环境
虚拟环境使用第三方实用工具virtualenv创建。输入一下命令可以检查系统是否安装了virtualenv
virtualenv --version
如果显示错误,你就需要安装这个工具。发行版
大多数Linux发行版都提供了virtualenv包。例如,Ubantu用户可以使用下述命令安装它:
sudo apt-gett install python-virtualenv
如果你的电脑是Mac OS X系统,就可以使用easy_install安装virtualenv:
sudo easy_install virtualenv
如果你使用windows系统或其他没有官方virtualenv包的操作系统,那么安装程序要稍微复杂一点。
windows安装virtuaalenv
1.windows下载虚拟环境virtualenv
https://bitbucket.org/pypa/setuptools
2.找到ez_setup.py并点击下载
3.在这个文件夹中以管理员身份执行以下命令:
python ez_setup.py
easy_install virtualenv
创建虚拟环境并激活
首先进入目标文件夹,然后执行virtualenv venv 创建虚拟环境
激活:venv\Scripts\activate
linu和Mac OS X :source venv/bin/activate
回到全局Python解释器:deactivate
安装flask
进入虚拟环境然后安装flask:pip install flask
完整的程序
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'hello.world'
if __name__ == '__main__':
app.run(debug=True)
flask-script支持命令行选项
安装:pip install flask-script
使用:
from flask.ext.script import Manager
app = Flask(__name__)
manager = Manager(app)
使用janja2模板渲染
templates/user.html
{% if name %}
<h1>hello,{{ name }}</h1>
{% else %}
<h1>hello,world</h1>
{% endif %}
hello.py
@app.route('/')
def index():
return render_template('user.html')
@app.route('/user/<name>')
def user(name):
return render_template('user.html',name=name)
使用Bootstrap集成Twitter Bootstrap
安装:pip install flask-bootstrap
导入:
from flask.ext.bootstrap import Bootstrap
app = Flask(__name__)
bootstrap = Bootstrap(app)
templates/user.html 使用bootstrap模板:
bootstrap中文网
使用 BootCDN 提供的免费 CDN 加速服务(同时支持 http 和 https 协议)
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
使用Flask-Moment本地化日期和时间
安装:pip install flask-moment
初始化:
from flask_moment import Moment
moment = Moment(app)
html中引入moment.js
{% block script %}
{{ super() }}
{{ moment.include_moment() }}
{% endblock %}
hello.py加入一个datatime变量
from flask_moment import Moment
from datetime import datetime
moment = Moment(app)
@app.route('/')
def index():
return render_template('index.html',current_time = datetime.utcnow())
模板中渲染current_time
<p>现在的时间是{{ moment(current_time).format('LLL') }}</p>
<p>That was {{ moment(current_time).fromNow(refresh=True) }}</p>
使用表单
安装:pip install flask_wtf
为了保护所有表单免受跨站请求伪造,需要设置一个密钥。和设置字典一样直接赋值
from flask_wtf import Form
from wtforms import StringField,SubmitField
from wtforms.validators import Required
app.config['SECRET_KEY'] = 'hard to guess string'
创建表单
class NameForm(Form):
name = StringField(u'你的名字')
submit = SubmitField(u'提交')
在视图函数中引入表单
@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'))
在HTML中渲染表单
{% import 'bootstrap/wtf.html' as wtf %}
<form method="post">
{{ wtf.quick_form(form) }}
</form>
flash消息
导入:from flask import flash
使用:
flash(‘’......‘’)
在html中渲染:
{% for message in get_flashed_messages() %}
<div class="alert alert-warning">
<button type="button" class="close" data-dismiss="alert">×</button>
{{ message }}
</div>
{% endfor %}
使用Flask-SQLAlchemy管理数据库
使用python连接mysql
首先安装mysql-python
linux:pip install mysql-python
windows:链接:www.lfd.uci.edu/~gohlke/pythonlibs/#mysql-python
点击MySQL_python-1.2.5-cp27-NONE-win32.whl下载
pip install MySQL_python-1.2.5-cp27-NONE-win32.whl安装
安装:pip install flask-sqlalchemy
导入
from flask_sqlalchemy import SQLAlchemy
import os
basedir = os.path.abspath(os.path.dirname(__file__))
app.config.from_object('config')
db = SQLAlchemy(app)
db.create_all()
在flask-sqlalchemy中,数据库使用URL指定。最流行的数据库引擎采用的数据库URL格式如下
数据库引擎 URL
Mysql mysql://username:password@hostname/database
Postgres postgresql://username:password@hostname/database
SQLite(Unix) sqlite:absolute/path/to/database
SQLITE(windows) sqlite:///c:/absolute/path/to/database
配置数据库:dialect+driver://username:password@host:port/databases
config.py
DIALECT = 'mysql'
DRIVER = 'mysqldb'
USERNAME = 'root'
PASSWORD = ' '
HOST = '127.0.0.1'
PORT = '3306'
DATABASES = 'dbdemo'
SQLALCHEMY_DATABASE_URI=\
'{}+{}://{}:{}@{}:{}/{}?charset=utf8'.format(DIALECT,DRIVER,USERNAME,PASSWORD,HOST,PORT,DATABASES)
SQLALCHEMY_COMMIT_ON_TEARDOWN=True
SQLALCHEMY_TRACK_MODIFICATIONS=False
创建表
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(64),unique=True)
users = db.relationship('User', backref='role')
def __repr__(self):
return '<Role %r>'%self.name
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True ,index=True)
role_id = db.Column(db.Integer,db.ForeignKey('role.id'))
def __repr__(self):
return '<User %r>' % self.username
使用工厂函数:
app/__init__.py:
from flask import Flask,render_template,url_for,redirect,session,flash
from flask_bootstrap import Bootstrap
from flask_moment import Moment
from flask_sqlalchemy import SQLAlchemy
from config import config
bootstrap = Bootstrap()
moment = Moment()
db = SQLAlchemy()
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
bootstrap.init_app(app)
moment.init_app(app)
db.init_app(app)
return app
在蓝本中实现程序功能:
app/main/__init__.py:
from flask import Blueprint
Blueprint('main',__name__)
from . import views,errors
app/__init__.py注册蓝本
def create_app(config_name)
from .main import main as main_bluprent
app.register_blueprint(main_bluprent)
return app
使用Werkzeug实现密码散列
app/models.py 在User模型中加入密码散列
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True,index=True)
role_id = db.Column(db.Integer,db.ForeignKey('roles.id'))
password_hash = db.Column(db.String(128))
@property
def password(self):
raise AttributeError('password is not a readable attribute')
@password.setter
def password(self,password):
self.password_hash = generate_password_hash(password)
def verify_password(self,password):
return check_password_hash(self.password_hash,password)
User表的静态方法:password错误会触发AttributeError
password_hash就是generate_password_hash生成的hash值
verify_password需要传入password,和password_hash比较,如果正确则返回True
在shell中测试:
(venv) python manage.py shell
>>> u = User()
>>> u.password = 'cat'
>>> u.password_hash
'pbkdf2:sha256:50000$wBooo1Ro$b3e3d42ce34ca1e886726cc94ccecf0b274c3de913876d508837d63aabd44b1c'
>>> u.verify_password('cat')
True
>>> u.verify_password('dog')
False
>>> u2 = User()
>>> u2.password = 'cat'
>>> u2.password_hash
'pbkdf2:sha256:50000$5mLqP9WH$8f4d60676d30eb2d4c3f4b9c16e19b468998b5fd4dea6cf48611469da432f8e2'
密码散列化测试:
tests/test_user_models.py
import unittest
from app.models import User
class UserModelTestCase(unittest.TestCase):
def test_password_setter(self):
u = User(password = 'cat')
self.assertTrue(u.password_hash is not None)
def test_no_password(self):
u = User(password = 'cat')
with self.assertRaises(AttributeError):
u.password
def test_password_verfication(self):
u = User(password = 'cat')
self.assertTrue(u.verify_password('cat'))
self.assertFalse(u.verify_password('dog'))
def test_password_salts_are_random(self):
u = User(password='cat')
u2 = User(password='cat')
self.assertTrue(u.password_hash != u2.password_has
创建认证蓝本
app/auth/__init__.py
from flask import Blueprint
auth = Blueprint('auth',__name__)
from . import views
在app/__init__中注册
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint,url_prefix='/auth')
app/auth/views.py
from flask import render_template
from . import auth
@auth.route('/login')
def login():
return render_template('auth/login.html')
使用Flask-login认证用户
*安装:pip install flask-login
准备用于登录的用户模型
Flask-Login要求实现的用户方法
*方法 说明
is_authenticated 如果用户已经登录,必须返回True,否则返回False
is_active 如果允许用户登录,必须返回True,否则返回False。如果要禁用用户,可以返回False
is_anonymous 对普通用户必须返回False
get_id 必须返回用户的唯一标识符,使用unicode编码字符串
*flask—login提供了一个UserMixin类,其中包含这些方法的默认实现,需要在数据库中继承
*初始化:
app/__init__.py:
from flask_login import LoginManager
login_manager = LoginManager()
login_manager.session_protection='strong'
login_manager.login_view = 'auth.login'
login_manager.session_protection属性可以设为None,‘basic’或‘strong’,以提供不同的安全等级防止用户会话遭篡改
设为strong时,会记录客户端IP地址和浏览器的用户代理信息,如果发现异动就登出用户。
login_view属性设置登录页面的端点
*最后,Flask_login要求程序实现一个回调函数,使用指定的标识符加载用户。
app/models.py
from . import login_manager
@login_manager.user_loader()
def load_user(user_id):
return User.query.get(int(user_id))
加载用户的回调函数接收Unicode字符串形式表示的用户标识符。如果能找到用户,这个函数必须返回用户对象;否则应该返回None
*保护路由
为了保护路由只让认证用户访问,Flask-login提供了一个login_required修饰器,未认证的用户访问这个路由,会拦截请求把用户发往登录页面
from flask_login import login_required
@app.route('/secret')
@login_required
def secret():
return 'Only authenticated users are allowed'
打开URL
manage.py
@manager.command
def dev():
from livereload import Server
live_server = Server(app.wsgi_app)
live_server.watch('**/*.*')
live_server.serve(open_url = True)