美文网首页Python Web
《Flask Web开发实战》—— 留言板实例

《Flask Web开发实战》—— 留言板实例

作者: 北邮郭大宝 | 来源:发表于2020-01-06 09:03 被阅读0次

继续学习Flask,把前面几节的内容做个实例——留言板。

0. 准备

创建项目,安装依赖的库

  • bootstrap-flask
  • flask
  • flask-wtf
  • flask-sqlalchemy
  • flask-moment
  • faker
  • python-dotenv

1. 项目结构

1578233339794.jpg
  • 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')}}

result:


1578235887443.jpg

index_bootstrap.html

{% extends 'base.html' %}
{% from 'bootstrap/form.html' import render_form %}
​
{% block content %}
<div class="hello-form">
    {{ render_form(form, action=request_full_path )}}
</div>
​
<h5>{{ messages|length }} messages
    <small class="float-right">
        <a href="#bottom" title="Go Buttom">&darr;</a>
    </small>
</h5>
<div class="list-group">
    {% for message in messages %}
        <a class="list-group-item list-group-item-action flex-column">
            <div class="d-flex w-100 justify-content-between">
                <h5 class="mb-1 text-success">
                    <small class="text-muted"> #{{ loop.revindex }}</small>
                    {{ message.name }}
                </h5>
                <small>
                    {{ moment(message.timestamp).fromNow(refresh=True) }}
                </small>
            </div>
            <p class="mb-1">{{ message.body }}</p>
        </a>
    {% endfor %}
</div>
{% 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.效果

1578235198697.jpg

8.总结

这里例子是对之前几个小节的总结,使用到了表单、数据库、视图函数等。新学习了Bootstrap-flask、Flask-Moment、Faker,但是学习的比较浅,只是简单用了一下,详细内容还需要深入了解下这三个库的使用。

详细内容见GitHub

相关文章

网友评论

    本文标题:《Flask Web开发实战》—— 留言板实例

    本文链接:https://www.haomeiwen.com/subject/nhxhactx.html