继续学习Flask,把前面几节的内容做个实例——留言板。
0. 准备
创建项目,安装依赖的库
bootstrap-flask
flask
flask-wtf
flask-sqlalchemy
flask-moment
faker
python-dotenv
1. 项目结构
static 静态文件,存放css、js等
templates 存模板,包括html
__init__.py 构造文件
commands.py 一些自定义flask命令
config.py 配置文件
errors.py 错误的处理
forms.py 表单
models.py 数据库模型
views.py 视图函数
2. 配置文件和创建实例
首先需要创建Flask实例,初始化,完成配置等操作。
__init__.py
from flask import Flask
from flask_bootstrap import Bootstrap
from flask_moment import Moment
from flask_sqlalchemy import SQLAlchemy
app = Flask("sayhello") # 程序包名称
app.config.from_pyfile('config.py') # 配置读取从config.py
app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True
db = SQLAlchemy(app) # init something
bootstrap = Bootstrap(app)
moment = Moment(app)
from sayhello import views, errors, commands
config.py
import os
from sayhello import app
db = 'sqlite:///' + os.path.join(os.path.dirname(app.root_path) + '/sayhello', 'data.db')
SECRET_KEY = os.getenv('SECRET_KEY', 'secret string')
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_DATABASE_URI = os.getenv('DATABASE_URI', db)
此外需要在.env中指明FLASK_APP和FLASK_ENV,否则定位不到flask app
3. 构造数据库
定义表Message,有id、body、name、timestamp四个字段。定义好后再用Flask自定义命令创建。
model.py
from datetime import datetime
from sayhello import db
class Message(db.Model):
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.String(200))
name = db.Column(db.String(20))
timestamp = db.Column(db.DateTime, default=datetime.utcnow, index=True)
commands.py
import click
from sayhello import app, db
@app.cli.command()
def initdb():
db.create_all()
click.echo("Initialized database.")
先执行pipenv shell,再执行flask initdb完成创建完成。
4. 编写表单类
定义表单类HelloForm
forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField, SubmitField
from wtforms.validators import DataRequired, Length
class HelloForm(FlaskForm):
name = StringField('Name', validators=[DataRequired(), Length(1, 20)])
body = TextAreaField('Message', validators=[DataRequired(), Length(1, 200)])
submit = SubmitField('Submit')
5. 编写视图函数和其他处理函数
完成视图函数,本例只有一个视图函数,完成留言板的提交和展示。
views.py
from flask import flash, render_template, redirect, url_for
from sayhello import app, db
from sayhello.models import Message
from sayhello.forms import HelloForm
@app.route('/', methods=['GET', 'POST'])
def index():
messages = Message.query.order_by(Message.timestamp.desc()).all()
form = HelloForm()
if form.validate_on_submit():
name = form.name.data
body = form.body.data
m = Message(name=name, body=body)
db.session.add(m)
db.session.commit()
flash("Your Message have been saved!")
redirect(url_for('index'))
return render_template('index_bootstrap.html', form=form, messages=messages)
这里使用bootstrap-flask快速渲染HTML,比如渲染表单,可以使用render_form,只需要传入表单名称即可.
使用flask-moment本地化日期和时间。
使用方法:
{{ moment(timestamp).format('格式字符串')}}
eg:
{{ moment(timestamp).format('LLL')}}
index_bootstrap.html
{% extends 'base.html' %}
{% from 'bootstrap/form.html' import render_form %}
{% block content %}
{{ render_form(form, action=request_full_path )}}
{{ messages|length }} messages
↓
{% for message in messages %}
#{{ loop.revindex }}
{{ message.name }}
{{ moment(message.timestamp).fromNow(refresh=True) }}
{{ message.body }}
{% endfor %}
{% endblock content %}
6. Faker生成虚拟数据
使用faker生成虚拟数据:Faker内置了20多类虚拟数据,包括姓名、地址、邮箱等等,使用起来也很方便,实例化Faker类,创建fake对象作为虚拟数据生成器。
这里使用Flask自定义命令完成虚拟数据的生产。
commands.py
@app.cli.command()
@click.option('--count', default=20, help='Quantity of messages, default is 20.')
def forge(count):
from faker import Faker
db.drop_all()
db.create_all()
fake = Faker('zh_CN') # 选择语言
click.echo('Working')
for i in range(count):
message = Message(
name=fake.name(),
body=fake.sentence(),
timestamp=fake.date_time_this_year()
)
db.session.add(message)
db.session.commit()
click.echo("Create %d fake messages." % count)
执行flask forge
7. 效果
8.总结
这里例子是对之前几个小节的总结,使用到了表单、数据库、视图函数等。新学习了Bootstrap-Flask、Flask-Moment、Faker,但是学习的比较浅,只是简单用了一下,详细内容还需要深入了解下这三个库的使用。
详细代码见Github