快乐学习
前程无忧、中华英才非你莫属!

Flask入门到精通-Day2

实战一:留言板

参考:Flask Web开发实战:入门、进阶与原理解析 中的留言板项目。
在它的基础上添加了mysql 数据库支持,和分页功能。

表结构:

CREATE TABLE `message`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `body` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `timestamp` datetime NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;


源码:

FlaskDemo.py

from flask import Flask,url_for,request,render_template,flash,redirect
from werkzeug.routing import BaseConverter
from flask_uploads import UploadSet, configure_uploads, IMAGES, patch_request_class
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileRequired, FileAllowed
from wtforms import SubmitField
# 数据库orm
from flask_sqlalchemy import SQLAlchemy
# UI类
from flask_bootstrap import Bootstrap
#国际化日期类
from flask_moment import Moment
from datetime import datetime
import time
import os


app = Flask(__name__)

######################################################################
# 留言板 运行环境配置

#配置数据库链接
app.config['SQLALCHEMY_DATABASE_URI'] ='mysql+pymysql://root:root@127.0.0.1:3306/mydb3'
#配置数据库出错不需要单独记录,如果做单独记录,就选true
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 数据库初始化,UI初始化,时间类、模板格式初始化
db = SQLAlchemy(app)
bootstrap = Bootstrap(app)
moment = Moment(app)
app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True


#####################################################################

# 留言板数据库ORM模型

#设计orm类,跟mysql的表结构一一对应。

class Message(db.Model):

    __tablename__ = 'message' #表名称
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20))
    body = db.Column(db.String(200))
    timestamp = db.Column(db.DateTime, default=datetime.utcnow, index=True)


##################################################################


# 留言板form表单处理逻辑

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, TextAreaField
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()

#######################################################################################
#留言板视图分页路由

@app.route('/paginate/',methods=['GET', 'POST'])
@app.route('/paginate/<int:page>')
def message_list(page=1):
 
  # 最新的时间排在最前面,直接调用flask写好的分页函数,配置页数,每页几条数据。
    messages= Message.query.order_by(Message.timestamp.desc()).paginate(page=page, per_page=3,error_out=False)

  #form 表单处理逻辑,当表单有post提交的时候,接收过来提交的数据,通过orm类存导mysql中,并返回当前url。

  # 没有表单的提交操作,直接返回
    form = HelloForm()
    if form.validate_on_submit():
        name = form.name.data
        body = form.body.data

        message = Message(body=body, name=name)
        db.session.add(message)
    db.session.commit()
        flash('Your message have been sent to the world!')
        return redirect(url_for('message_list'))

    return render_template('index_list.html',form=form,messages=messages.items,pagination=messages)

#############################################################################################


if __name__ == '__main__':
    app.run(debug=1)


分页导航:page.html

{% macro my_paginate(pagination,url) %}
<nav>
    <ul class="pagination">

        {%if pagination.has_prev%}
        <li class="page-item active"><a class="page-link" href="{{url_for(url,page=pagination.page-1)}}">上一页</a></li>
        {%else%}
        <li class="page-item disabled"><a class="page-link" href="#">上一页</a></li>
        {%endif%}

            {%for page in pagination.iter_pages(1,1,3,1)%}
            {%if page%}
                <li class="page-item {%if page==pagination.page%}active{%endif%}"><a class="page-link" href="{{url_for(url,page=page)}}">{{page}}</a></li>
            {%else%}
                <li class="page-item disabled"><a class="page-link" href="#">&hellip;</a></li>
            {%endif%}

        {%endfor%}

        {%if pagination.has_next%}
        <li class="page-item active"><a class="page-link" href="{{url_for(url,page=pagination.page+1)}}">下一页</a></li>
        {%else%}
        <li class="page-item disabled"><a class="page-link" href="#">下一页</a></li>
        {%endif%}

    </ul>
</nav>

{%endmacro%}

主页显示页面‘index_list.html

{% extends 'base.html' %}

{% from 'bootstrap/form.html' import render_form %}
{% import 'pages.html' as pg%} <!-- 引入分页导航 -->

{% 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 Bottom">&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">{{ message.name }}
                        <small class="text-muted"> #{{ loop.revindex }}</small>
                    </h5>
                    <small data-toggle="tooltip" data-placement="top"
                           data-timestamp="{{ message.timestamp.strftime('%Y-%m-%dT%H:%M:%SZ') }}"
                           data-delay="500">
                        {{ moment(message.timestamp).fromNow(refresh=True) }}
                    </small>
                </div>
                <p class="mb-1">{{ message.body }}</p>
            </a>

        {% endfor %}
    </div>


    <!-- 引入分页导航-->
    <div class="pagination"
    {{pg.my_paginate(pagination,'message_list')}}
    </div>
    
{% endblock %}



打赏

未经允许不得转载:同乐学堂 » Flask入门到精通-Day2

分享到:更多 ()

评论 1

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #1

    呵呵。学习了。感触良多!

    罗拉2年前 (2018-09-29)回复

特别的技术,给特别的你!

联系QQ:1071235258QQ群:226134712
error: Sorry,暂时内容不可复制!