美文网首页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