PythonWeb之路:flask第六篇

点击名片关注 阿尘blog,一起学习,一起成长

1 使用Flask-Bootstap集成Bootstrap

Bootstrap是Twitter开发的一个开源的Web框架,提供了用户界面组件可用于创建整洁且具有吸引力的网页,兼容桌面和移动Web,flask要集成Bootstrap就要利用flask的拓展:Flask-Bootstrap

安装flask-bootstrap

pip install flask-bootstrap

初始化Bootstrap

from flask import Flask  
from flask_bootstrap import Bootstrap  
app = Flask(__name__)
# 初始化bootstrap
bootstrap = Bootstrap(app)  
@app.route('/index')
def index():
    return render_template('index.html',name='阿尘')

index.html

{% extends "bootstrap/base.html" %}

{% block title %}Flask-Bootstrap Example{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle"
            data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/">Flasky</a>
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li><a href="/">Home</a></li>
            </ul>
        </div>
    </div>
</div>
{% endblock %}
{% block content %}
<div class="container">
    <div class="page-header">
        <h1>Hello,{{ name }}</h1>
    </div>
</div>
{% endblock %}
e78ab082a10d4edcf9491290d9ddc621.png

在jinja2中,extend指令从flask-bootstrap中导入bootstrap/base.html从而实现模板的继承 在index模板中我们定义了三个区块,title、navbar、content

如果要在衍生模板中使用新的JavaScript文件那么需要如下定义新的scripts区块

{% block scripts %}
{{ super() }}
<scripts type="text/javascript" src="your-own-script.js"></scripts>
{% endblock %}

当然你也可以自己定义一个二级基础模板放在templates里面

{% extends "bootstrap/base.html" %}

{% block title %}Flask-Bootstrap Example{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle"
            data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/">Flasky</a>
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li><a href="/">Home</a></li>
            </ul>
        </div>
    </div>
</div>
{% endblock %}
{% block content %}
<div class="container">
   {% block page_content %}{% endblock %}
</div>
{% endblock %}

有了这个模板我们可以不用直接继承flask-bootstrap的基模板,而用这个来自定义其他页面,比如404页面

{% extends 'base.html' %}
{% block title %}Flasky- Page Not Found{% endblock %}
{% block page_content %}
<div class="page-header">
    <h1>Not Found</h1>
</div>
{% endblock %}
297e505176eac9c06d8f5d5a3ab9a30e.png

2 使用Flask-Moment本地化日期和时间

web应用的用户如果来自世界各地,处理时间就是一个复杂的任务,一般使用协调世界时间(UTC)再把UTC转化为用户习惯的当地时间格式,要做到这样可以把时间单位发给web然后采用JavaScript渲染。

有一个JavaScript开发的客户端开源库:Moment.js,可以对浏览器的日期和时间进行渲染,而Flask的一个扩展,Flask-Moment就简化了Moment.js集成到了Jinja2模板中的过程

安装Flask-Moment

pip install flask-moment

初始化Flask-Moment

from flask_moment import Moment 
from flask import Flask  
app = Flask(__name__) 
moment = Moment(app)

然后在templates/base.html引入Moment.js库,放在任何位置都可以

{% endblock %}
{% block scripts %}
{{ super() }}
{{ moment.include_moment() }}
{% endblock %}

然后修改app.py

from datetime import datetime
@app.route('/index')
def index():
    return render_template('index.html',current_time=datetime.utcnow())

渲染index.html

{% block content %}
<div class="container">
    <p>当地日期和时间为{{ moment(current_time).format('LLL') }}.</p>
    <p>当前页面停留{{ moment(current_time).fromNow(refresh=True) }}</p>
</div>
{% endblock %}

format()函数的L代表时间复杂程度

第二行是会随着时间推移刷新

54241be229f8bc9fda321ca3a5cf5b9f.png

具体还有其他方法,可以参考官网

渲染的时间还可以切换不同语言,这需要在引入momen.js,将语言代码传给locale()函数

{% block scripts %}
{{ super() }}
{{ moment.include_moment() }}
{{ moment.locale('zh-CN') }}
{% endblock %}
fec7fd01ef0e4071f9ce01eda4ef0288.png

3 Web表单

之前在第四篇分享文章中,实现登录页面,里面有使用表单,但是那是我直接在html模板文件中创建的表单,flask-wtf扩展集成WTForms,支持在Python中使用类定义表单,然后直接通过类定义生成对应的HTML代码,这种方式更加方便,而且使表单更易于重用。

安装flask-wtf

pip install flask-wtf

为了防治表单遭到攻击,flask-wtf要求应用配置一个秘钥

app.secret_key = 'secret string'

表单类:在用flask-wtf时,每个web表单都有一个继承自FlaskForm的类表示,这个类定义了表单中的一组字段,每个字段都用对象表示,字段还可以复数一个或多个验证码函数用于验证用户提交的数据是否 有效:下面WebForm.py

from flask_wtf import FlaskForm
from wtforms import StringField,SubmitField,PasswordField,BooleanField
from wtforms.validators import DataRequired
class LoginForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    password = PasswordField('Password', validators=[DataRequired(), Length(6, 18)])
    remember = BooleanField('Remember me')
    submit = SubmitField('Log in')

WTForms支持的HTML标准字段

362ec558028d78463050f04b1da3780f.png

通过实例化字段类时传入的参数,我们可以对字段进行设置,字段类构造方法接收的常用参数如表

0df699c965ea66e3a17f510d14fc9b39.png

WTForms中,验证器(validator)是一系列用于验证字段数据的类,我们在实例化字段类时使用validators关键字来指定附加的验证器列表。验证器从wtforms.validators模块中导入,常用的验证器如表:

6de8afee6a7301bbe956549c94e818df.png

验证器的第一个参数一般为错误提示消息,我们可以使用message关键字传递参数,通过传入自定义错误信息来覆盖内置消息

创建完表单类,我们就可调用来获取对应HTML代码

from webForm import LoginForm # 导入写的表单类
from flask import Flask,render_template,redirect,url_for
import secrets
app = Flask(__name__)
app.secret_key = secrets.token_hex(16)
@app.route('/')
def index():
    return redirect(url_for('login'))
@app.route('/login')
def login():
    # 实例化表单
    login_form = LoginForm()
    return render_template('login.html',form = login_form)

在模板中渲染表单:login.html,Bootstrap风格

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login Page</title>
   <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk5gwnNi8nXn50KGpyuVoXckpaBVifq0Ei7gykkjaj温xkfa90" crossorigin="anonymous">
</head>
<body>
    <form method="post" class="container-lg">
{{ form.csrf_token }}
	<div class="form-group">
		{{ form.username.label }}
		{{ form.username(class='form-control') }}
	</div>
	<div class="form-group">
		{{ form.password.label }}
		{{ form.password(class='form-control') }}
	</div>
	<div class="form-check">
		{{ form.remember(class='form-check-input') }}
		{{ form.remember.label }}
	</div>
		{{ form.submit(class='btn btn-primary') }}
</form>



</body>
</html>
05ca0431f4a703a13ca0761ac1ac8e0e.png

处理表单,在视图函数中处理表单

@app.route('/login',methods=['GET','POST'])
def login():
    # 实例化表单
    login_form = LoginForm()
    if login_form.validate_on_submit():
        if login_form.username == 'jonas' and login_form.password == 'a123456':
            flash(f'登陆成功,欢迎用户{login_form.username}!',category='success')
            return redirect(url_for('welcome'))
        else:
            flash('登录失败!请重新登陆')
            return redirect(url_for('login'))
    return render_template('login.html',form = login_form)
@app.route('/welcome')
def welcome():
    return 'Welcome!'

如上通过对前端传回的请求进行处理判断,而在这个视图中我们添加了闪现消息,闪现消息也就是常见的弹窗提示,通过flash()函数发送消息,flash()函数有两个参数,一个是message字段(必填),一个是类别字段(选填),flash推送的消息是由数组组成的列表,所以也可以循环

闪现消息的模板渲染:

{% with messages = get_flashed_messages(with_categories=true) %}
            {% if messages %}
                <ul class="container-lg">
                {% for category ,message  in messages %}
                     {% if category == 'success' %}
                        <div class="alert-success">{{ message }}</div>
                     {% else %}
                         <div class="alert-warning">{{ message }}</div>
                     {% endif %}
                {% endfor %}
                </ul>
            {% endif %}
    {% endwith %}

这里面的样式我同样采用的上述bootstrap.css进行渲染

实际效果

f0a228c271da2edc92fa3512af50ec76.png

扫描二维码关注阿尘blog,一起交流学习

353ac45a88ca0b615f582f38fe708411.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是阿尘呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值