Flask-web开发

使用虚拟环境

虚拟环境使用第三方实用工具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 创建虚拟环境
激活:venvScriptsactivate
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)

  

原文地址:https://www.cnblogs.com/liushaocong/p/7225139.html