Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。
官方建议使用 Python 2.6 或 2.7 开发, Python 3 还有些问题没解决。如已安装有 Python 3 了,可以使用 virtualenv 创建使用 python 2.7 的虚拟环境。示例比较简单,使用的数据库为 sqlite,因此先安装好 sqlite。
创建项目文件夹 flaskr,并在其目录下手动创建以下文件夹和文件(除了数据文件 flaskr.db)
安装必要模块:
pip install FlaskPython主要开发脚本文件: flaskr.py
#-*- coding: utf-8 -*- # python 2.7 import sqlite3 from contextlib import closing from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash #import os #basedir = os.path.abspath(os.path.dirname(__file__)) # 创建应用的模块 DATABASE = 'D:/Python35/mypy/project/flaskr/tmp/flaskr.db' USERNAME = 'admin' #网页的登录用户及密码 PASSWORD = 'admin' DEBUG = True #调试模式,代码变更时自动加载不必每次重启服务 SECRET_KEY = 'development key' #保持客户端的会话安全,尽可能复杂 # 配置初始化 # create our little application :) app = Flask(__name__) app.config.from_object(__name__) #搜寻里面定义的全部大写的变量 #设置一个名为 FLASKR_SETTINGS 环境变量来设定一个配置文件载入后是否覆盖默认值 #app.config.from_envvar('FLASKR_SETTINGS', silent=True) #连接到指定数据库 def connect_db(): return sqlite3.connect(app.config['DATABASE']) #初始化数据库(或者:sqlite3 ./tmp/flaskr.db < schema.sql) def init_db(): with closing(connect_db()) as db: with app.open_resource('schema.sql') as f: db.cursor().executescript(f.read()) db.commit() """ >>> from flaskr import init_db >>> init_db() """ # 连接 @app.before_request def before_request(): g.db = connect_db() #关闭 @app.teardown_request def teardown_request(exception): if hasattr(g, 'db'): g.db.close() #显示表 entries记录 (http://127.0.0.1:5000) @app.route('/') #URL相对路径 def show_entries(): cur = g.db.execute('select title, text from entries order by id desc') entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()] #转为字典格式 return render_template('show_entries.html', entries=entries) #显示页调用模板 show_entries.html,传回数据entries #添加记录到表 entries (http://127.0.0.1:5000/add) @app.route('/add', methods=['POST']) #只回应 POST 请求 def add_entry(): if not session.get('logged_in'): #获取用户登录,是否为True abort(401) g.db.execute('insert into entries (title, text) values (?, ?)',[request.form['title'], request.form['text']]) g.db.commit() flash('New entry was successfully posted') #闪现信息 return redirect(url_for('show_entries')) #返回显示页面 #登录 (http://127.0.0.1:5000/login) @app.route('/login', methods=['GET', 'POST']) def login(): error = None if request.method == 'POST': if request.form['username'] != app.config['USERNAME']: error = 'Invalid username' elif request.form['password'] != app.config['PASSWORD']: error = 'Invalid password' else: session['logged_in'] = True flash('You were logged in') return redirect(url_for('show_entries'))#返回显示页面 return render_template('login.html', error=error) #登录页调用模板 login.html #注销 @app.route('/logout') def logout(): session.pop('logged_in', None) #移除键logged_in,键不存在则什么都不做 flash('You were logged out') return redirect(url_for('show_entries'))#返回显示页面 if __name__ == '__main__': app.run(host='0.0.0.0') #侦听所有地址
数据库脚本文件:schema.sql
drop table if exists entries; create table entries ( id integer primary key autoincrement, title string not null, text string not null );web主要文件: layout.html
<!doctype html> <title>Flaskr</title> <!-- 引用样式文件./static/style.css--> <link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}"> <div class=page> <h1>Flaskr</h1> <div class=metanav> {% if not session.logged_in %} <a href="{{ url_for('login') }}">log in</a> <!-- 如未登录,显示登录链接: "log in" --> {% else %} <a href="{{ url_for('logout') }}">log out</a><!-- 如已登录,显示注销链接: "log out" --> {% endif %} </div> {% for message in get_flashed_messages() %} <div class=flash>{{ message }}</div> <!-- 如有闪现信息则显示信息 --> {% endfor %} {% block body %}{% endblock %} <!-- 可用子模块同名body替换 --> </div>web数据显示文件: show_entries.html
{% extends "layout.html" %} <!-- 继承 layout.html 模版用来显示信息--> {% block body %} <!-- 替换 layout.html 的body模块显示信息 --> {% if session.logged_in %} <!-- 如果已登录,则显示添加记录表单 --> <form action="{{ url_for('add_entry') }}" method=post class=add-entry> <dl> <dt>Title: <dd><input type=text size=30 name=title> <dt>Text: <dd><textarea name=text rows=5 cols=40></textarea> <dd><input type=submit value=Adding> </dl> </form> {% endif %} <!-- 遍历entries显示数据 --> <ul class=entries> {% for entry in entries %} <li><h2>{{ entry.title }}</h2>{{ entry.text|safe }} {% else %} <li><em>Unbelievable. No entries here so far (当前表无数据)</em> {% endfor %} </ul> {% endblock %}web登录文件: login.html
{% extends "layout.html" %} <!-- 继承 layout.html 模版用来显示信息--> {% block body %} <!-- 替换 layout.html 的body模块显示信息 --> <h2>Login</h2> <!-- 显示登录验证信息 --> {% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %} <form action="{{ url_for('login') }}" method=post> <dl> <dt>Username: <dd><input type=text name=username> <dt>Password: <dd><input type=password name=password> <dd><input type=submit value=Login> </dl> </form> {% endblock %}
样式文件:style.css
body { font-family: sans-serif; background: #eee; } a, h1, h2 { color: #377BA8; } h1, h2 { font-family: 'Georgia', serif; margin: 0; } h1 { border-bottom: 2px solid #eee; } h2 { font-size: 1.2em; } .page { margin: 2em auto; width: 35em; border: 5px solid #ccc; padding: 0.8em; background: white; } .entries { list-style: none; margin: 0; padding: 0; } .entries li { margin: 0.8em 1.2em; } .entries li h2 { margin-left: -1em; } .add-entry { font-size: 0.9em; border-bottom: 1px solid #ccc; } .add-entry dl { font-weight: bold; } .metanav { text-align: right; font-size: 0.8em; padding: 0.3em; margin-bottom: 1em; background: #fafafa; } .flash { background: #CEE5F5; padding: 0.5em; border: 1px solid #AACBE2; } .error { background: #F0D6D6; padding: 0.5em; }
对数据表的创建,有两种方法:
sqlite3 ./tmp/flaskr.db < schema.sql或者在python中执行初始化db函数 :init_db
from flaskr import init_db init_db()
运行应用:
python flaskr.py
浏览器打开网址:http://127.0.0.1:5000/
操作示例:
参考:欢迎使用 Flask