Flask:03-你离最美的web只差一个:bootstrap与表单

Posted Sunwj_Monkey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask:03-你离最美的web只差一个:bootstrap与表单相关的知识,希望对你有一定的参考价值。

bootstrap与表单

Bootstrap是美国Twitter公司的设计师Mark Otto和Jacob Thornton合作基于html、CSS、javascript 开发的简洁、直观、强悍的前端开发框架,使得 Web 开发更加快捷. Bootstrap提供了优雅的HTML和CSS规范,它即是由动态CSS语言Less写成。Bootstrap一经推出后颇受欢迎,一直是GitHub上的热门开源项目,包括NASA的MSNBC(微软全国广播公司)的BreakingNews都使用了该项目。国内一些移动开发者较为熟悉的框架,如WeX5前端开源框架等,也是基于Bootstrap源码进行性能优化而来。

flask-boostrap

  • 说明:在flask中使用bootstrap,可以通过该扩展库完成。

  • 安装:pip install flask-bootstrap

  • 使用:

    from flask_bootstrap import Bootstrap
    
    bootstrap = Bootstrap(app)
    
  • 模板

    {# 继承自bootstrap基础模板 #}
    {% extends \'bootstrap/base.html\' %}
    
    {% block title %}标题{% endblock %}
    
    {% block content %}
        <div class="container">默认内容</div>
    {% endblock %}
    
  • bootstrap基础模板中的block

    block说明
    doc 整个HTML文档
    html 整个html标签
    head 整个head标签
    metas 一组meta标签
    styles 一组link标签
    body 整个body标签
    navbar 导航条
    content 页面内容
    scripts 一组scripts标签

    提示:当重写一个block后,原来的显示效果全没了,很可能是因为没有写{{ super() }}

加载静态资源

  • flask中静态资源默认存放在static目录下,因此目录结构如下:

    project/        # 项目目录
        manage.py            # 启动控制文件
        templates/            # 模板文件目录
        static/                # 静态资源目录
            img/                # 图片
            css/                # css文件
            js/                    # js文件
            favicon.ico            # 收藏夹图标
    
  • 加载静态资源文件

    {# 继承自自定义的基础模板 #}
    {% extends \'base.html\' %}
    
    {% block title %}用户登录{% endblock %}
    
    {% block page_content %}
        <h1>欢迎登录...</h1>
        <div class="test"></div>
        {# 加载图片资源 #}
        {# 静态资源加载的目录static,提前在img文件夹保存一个图片xxx.jpg #}
        <img width="300" src="{{ url_for(\'static\', filename=\'img/xxx.jpg\') }}">
    {% endblock %}
    
    {% block styles %}
        {{ super() }}
        {# 加载CSS文件:css文件可以从bootstrap中粘贴一个过来 #}
        <link href="{{ url_for(\'static\', filename=\'css/common.css\') }}" type="text/css" rel="stylesheet" />
    {% endblock %}
    
    {% block head %}
        {{ super() }}
        {# 加载网站收藏夹小图标:ico文件自行从百度下载一个ico文件 #}
        <link rel="icon" type="image/x-icon" href="{{ url_for(\'static\', filename=\'favicon.ico\') }}" />
    {% endblock %}
    
    {% block scripts %}
        {{ super() }}
        {# 加载JS文件:js文件可以从bootstrap中粘贴一个过来 #}
        <script type="text/javascript" src="{{ url_for(\'static\', filename=\'js/common.js\') }}"></script>
    {% endblock %}
    

原生表单

  • 准备模板文件

    <form method="get" action="{{ url_for(\'check\') }}">
        用户名:<input name="username" /><br />
        <input type="submit" />
    </form>
    
  • 添加视图函数,渲染模板文件

    @app.route(\'/login/\')
    def login():
        return render_template(\'login.html\')
    
  • 校验提交的请求

    @app.route(\'/check/\', methods=[\'GET\', \'POST\'])
    def check():
        # args:所有的GET参数
        # return request.args.get(\'username\', \'提交失败\')
        # form:所有的POST参数
        # return request.form.get(\'username\', \'提交失败\')
        # values:所有的GET/POST参数
        return request.values.get(\'username\', \'提交失败\')
    
  • 一个路由可以接收多种请求

    @app.route(\'/login/\', methods=[\'GET\', \'POST\'])
    def login():
        if request.method == \'POST\':
            return request.form.get(\'username\', \'登录失败\')
        return render_template(\'login.html\')
    

flask-wtf

  • 说明:表单处理的扩展库,提供了CSRF、字段校验等实用功能,实用非常方便。

  • 安装:pip install flask-wtf

  • 使用:

    • 创建表单类:
    # 导入表单类的基类
    from flask_wtf import FlaskForm
    # 导入字段类型
    from wtforms import StringField, SubmitField
    # 导入相关验证器
    from wtforms.validators import Length
    
    # 创建表单类
    class NameForm(FlaskForm):
        # name = StringField(\'用户名\')
        # submit = SubmitField(\'提交\')
        name = StringField(\'用户名\', validators=[Length(3, 6, message=\'用户名必须是3~6个字符\')])
        submit = SubmitField(\'提交\')
    
    • 添加视图函数,创建表单对象,并分配的模板中
      @app.route(\'/\', methods=[\'GET\', \'POST\'])
      def index():
          # 创建表单对象
          form = NameForm()
          # 判断是否是有效的提交
          if form.validate_on_submit():
              return form.name.data
          # 在模板文件中渲染表单,form.html可以自己写一个,也可以百度一个
          return render_template(\'form.html\', form=form)
    
  • 原生渲染表单

    {# 原生渲染 #}
    <form method="post">
        {# CSRF字段 #}
        {{ form.hidden_tag() }}
        {# name字段 #}
        {{ form.name.label() }}{{ form.name(id=\'xx\', class=\'yy\') }}
        {% for e in form.name.errors %}
            <div>{{ e }}</div>
        {% endfor %}
        {# 提交按钮 #}
        {{ form.submit() }}
    </form>
    
  • 使用bootstrap进行渲染

    {% extends \'bootstrap/base.html\' %}
    
    {# 导入快速渲染表单的宏 #}
    {% from \'bootstrap/wtf.html\' import quick_form %}
    
    {% block title %}bootstrap渲染表单类{% endblock %}
    
    {% block content %}
        <div class="container">
            {# 在合适的位置渲染表单 #}
            {{ quick_form(form) }}
        </div>
    {% endblock %}
    
  • POST重定向到GET:浏览器会记录最后的请求状态,若最后请求时POST,点击刷新时会提示再次提交表单。

    @app.route(\'/\', methods=[\'GET\', \'POST\'])
    def index():
        # 创建表单对象
        form = NameForm()
        # 判断是否是有效的提交
        if form.validate_on_submit():
            session[\'name\'] = form.name.data
            return redirect(url_for(\'index\'))
        name = session.get(\'name\')
        # 在模板文件中渲染表单
        return render_template(\'form2.html\', form=form, name=name)
    
  • 常见字段类型:请自行测试

    字段类型说明
    StringField 普通文本
    SubmitField 提交按钮
    PasswordField 密文文本
    HiddenField 隐藏字段
    RadioField 单选框
    BooleanField 复选框
    SelectField 下拉框
    FileField 文件上传
    TextAreaField 文本域
    IntegerField 文本字段,值为整数
    FloatField 文本字段,值为浮点数
    DateField datetime.date类型
    DateTimeField datetime.datetime类型
  • 常见验证器:请自行测试

    验证器说明
    Length 规定字符长度
    DataRequired 确保字段有值(提示信息与所写的不一致)
    Email 邮箱格式
    IPAddress IP地址
    NumberRange 数值的范围
    URL 统一资源定位符格式
    EqualTo 验证两个字段的一致性
    Regexp 正则校验
  • 自定义字段验证函数

    # 创建表单类
    class NameForm(FlaskForm):
          。。。
        # 字段校验函数:\'validate_字段名\'
        def validate_name(self, field):
            if len(field.data) < 6:
                raise ValidationError(\'用户名不能少于6个字符\')
    

消息闪烁

  • 说明:

    当用户发出请求后,状态发生了改变,需要系统给出警告提示等信息时,通常都是弹出一条消息,指示用户下一步的操作,用户可以手动关闭或自动消失,整个过程不会影响页面的正常显示。

  • 使用:

    • 在需要闪烁消息时,使用flash函数保存闪烁消息
    @app.route(\'/\', methods=[\'GET\', \'POST\'])
    def index():
        # 创建表单对象
        form = NameForm()
        # 判断是否是有效的提交
        if form.validate_on_submit():
            # 最后一次提交的名字
            last_name = session.get(\'name\')
            # 如果存在最后提交的名字,且最后提交的名字与之前保存的名字不相同时
            if last_name and last_name != form.name.data:
                flash(\'大哥,又换名字了^_^\')
            session[\'name\'] = form.name.data
            return redirect(url_for(\'index\'))
        name = session.get(\'name\')
        # 在模板文件中渲染表单
        return render_template(\'form2.html\', form=form, name=name)
    
    • 在模板文件中提供get_flashed_messages函数获取闪烁消息并渲染:
    {% for message in get_flashed_messages() %}
    {# 闪烁消息文件可以从bootstrap中粘贴一个过来 #}
    <div class="alert alert-warning alert-dismissible" role="alert">
        <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span>
        </button>
        {{ message }}
    </div>
    {% endfor %}
    

    说明:上面是从bootstrap粘贴的可消失的警告框。

flask-moment

  • 说明:专门负责数据本地化显示的扩展库,使用非常方便。

  • 安装:pip install flask-moment

  • 使用:

    • python代码:
    from flask_moment import Moment
    
    moment = Moment(app)
    
    @app.route(\'/moment/\')
    def mom():
        from datetime import datetime, timedelta
        current_time = datetime.utcnow() + timedelta(seconds=-360)
        return render_template(\'mom.html\', current_time=current_time)
    
    • 模板文件:
    {# 加载jQuery:依赖 #}
    {{ moment.include_jquery() }}
    
    {# 加载moment #}
    {{ moment.include_moment() }}
    
    {# 设置语言 #}
    {{ moment.locale(\'zh-CN\') }}
    
    {# 简单的格式化时间显示 #}
    <div>时间:{{ moment(current_time).format(\'LLLL\') }}</div>
    <div>时间:{{ moment(current_time).format(\'LLL\') }}</div>
    <div>时间:{{ moment(current_time).format(\'LL\') }}</div>
    <div>时间:{{ moment(current_time).format(\'L\') }}</div>
    
    {# 自定义格式化时间显示:如2018-05-20 01:03:14 #}
    <div>自定义:{{ moment(current_time).format(\'YYYY-MM-DD HH:mm:ss\') }}</div>
    
    {# 显示时间差 #}
    <div>发表于:{{ moment(current_time).fromNow() }}</div>
    
ios9v+eUqO+8mjxicj48 YnI+Jm5ic3A7IC0g5Yib5bu66KGo5Y2V57G777yaPGJyPjxicj4mbmJzcDsgYGBgcHl0aG9uPGJy PiZuYnNwOyAjIOWvvOWFpeihqOWNleexu+eahOWfuuexuzxicj4mbmJzcDsgZnJvbSBmbGFza193 dGYgaW1wb3J0IEZsYXNrRm9ybTxicj4mbmJzcDsgIyDlr7zlhaXlrZfmrrXnsbvlnos8YnI+Jm5i c3A7IGZyb20gd3Rmb3JtcyBpbXBvcnQgU3RyaW5nRmllbGQsIFN1Ym1pdEZpZWxkPGJyPiZuYnNw OyAjIOWvvOWFpeebuOWFs+mqjOivgeWZqDxicj4mbmJzcDsgZnJvbSB3dGZvcm1zLnZhbGlkYXRv cnMgaW1wb3J0IExlbmd0aDxicj48YnI+Jm5ic3A7ICMg5Yib5bu66KGo5Y2V57G7PGJyPiZuYnNw OyBjbGFzcyBOYW1lRm9ybShGbGFza0Zvcm0pOjxicj4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsgIyBuYW1lID0gU3RyaW5nRmllbGQoJ+eUqOaIt+WQjScpPGJyPiZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyAjIHN1Ym1pdCA9IFN1Ym1pdEZpZWxkKCfmj5DkuqQnKTxicj4mbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgbmFtZSA9IFN0cmluZ0ZpZWxkKCfnlKjmiLflkI0n LCB2YWxpZGF0b3JzPVtMZW5ndGgoMywgNiwgbWVzc2FnZT0n55So5oi35ZCN5b+F6aG75pivM342 5Liq5a2X56ymJyldKTxicj4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgc3VibWl0ID0g U3VibWl0RmllbGQoJ+aPkOS6pCcpPGJyPiZuYnNwOyBgYGA8YnI+PGJyPiZuYnNwOyAtIOa3u+WK oOinhuWbvuWHveaVsO+8jOWIm+W7uuihqOWNleWvueixoe+8jOW5tuWIhumFjeeahOaooeadv+S4 rTxicj48YnI+Jm5ic3A7IGBgYHB5dGhvbjxicj4mbmJzcDsmbmJzcDsmbmJzcDsgQGFwcC5yb3V0 ZSgnLycsIG1ldGhvZHM9WydHRVQnLCAnUE9TVCddKTxicj4mbmJzcDsmbmJzcDsmbmJzcDsgZGVm IGluZGV4KCk6PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAj IOWIm+W7uuihqOWNleWvueixoTxicj4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsgZm9ybSA9IE5hbWVGb3JtKCk8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7ICMg5Yik5pat5piv5ZCm5piv5pyJ5pWI55qE5o+Q5LqkPGJyPiZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBpZiBmb3JtLnZhbGlkYXRlX29u X3N1Ym1pdCgpOjxicj4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgcmV0dXJuIGZvcm0ubmFtZS5kYXRhPGJyPiZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAjIOWcqOaooeadv+aWh+S7tuS4rea4 suafk+ihqOWNlSxmb3JtLmh0bWzlj6/ku6Xoh6rlt7HlhpnkuIDkuKrvvIzkuZ/lj6/ku6Xnmb7l uqbkuIDkuKo8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IHJl dHVybiByZW5kZXJfdGVtcGxhdGUoJ2Zvcm0uaHRtbCcsIGZvcm09Zm9ybSkgJm5ic3A7PGJyPiZu YnNwOyBgYGA8YnI+PGJyPjxicj4tIOWOn+eUn+a4suafk+ihqOWNlTxicj48YnI+Jm5ic3A7IGBg YGh0bWw8YnI+Jm5ic3A7IHsjIOWOn+eUn+a4suafkyAjfTxicj4mbmJzcDsgJmx0O2Zvcm0gbWV0 aG9kPSJwb3N0IiZndDs8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IHsjIENTUkbl rZfmrrUgI308YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IHt7IGZvcm0uaGlkZGVu X3RhZygpIH19PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyB7IyBuYW1l5a2X5q61 ICN9PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyB7eyBmb3JtLm5hbWUubGFiZWwo KSB9fXt7IGZvcm0ubmFtZShpZD0neHgnLCBjbGFzcz0neXknKSB9fTxicj4mbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsgeyUgZm9yIGUgaW4gZm9ybS5uYW1lLmVycm9ycyAlfTxicj4mbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgJmx0O2Rp diZndDt7eyBlIH19Jmx0Oy9kaXYmZ3Q7PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyB7JSBlbmRmb3IgJX08YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IHsjIOaPkOS6 pOaMiemSriAjfTxicj4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsge3sgZm9ybS5zdWJt aXQoKSB9fTxicj4mbmJzcDsgJmx0Oy9mb3JtJmd0Ozxicj4mbmJzcDsgYGBgPGJyPjxicj4tIOS9 v+eUqGJvb3RzdHJhcOi/m+ihjOa4suafkzxicj48YnI+Jm5ic3A7IGBgYGh0bWw8YnI+Jm5ic3A7 IHslIGV4dGVuZHMgJ2Jvb3RzdHJhcC9iYXNlLmh0bWwnICV9PGJyPjxicj4mbmJzcDsgeyMg5a+8 5YWl5b+r6YCf5riy5p+T6KGo5Y2V55qE5a6PICN9PGJyPiZuYnNwOyB7JSBmcm9tICdib290c3Ry YXAvd3RmLmh0bWwnIGltcG9ydCBxdWlja19mb3JtICV9PGJyPjxicj4mbmJzcDsgeyUgYmxvY2sg dGl0bGUgJX1ib290c3RyYXDmuLLmn5PooajljZXnsbt7JSBlbmRibG9jayAlfTxicj48YnI+Jm5i c3A7IHslIGJsb2NrIGNvbnRlbnQgJX08YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 ICZsdDtkaXYgY2xhc3M9ImNvbnRhaW5lciImZ3Q7PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyB7IyDlnKjlkIjpgILnmoTkvY3nva7muLLm n5PooajljZUgI308YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7IHt7IHF1aWNrX2Zvcm0oZm9ybSkgfX08YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7ICZsdDsvZGl2Jmd0Ozxicj4mbmJzcDsgeyUgZW5kYmxvY2sgJX08YnI+Jm5i c3A7IGBgYDxicj48YnI+LSBQT1NU6YeN5a6a5ZCR5YiwR0VU77ya5rWP6KeI5Zmo5Lya6K6w5b2V 5pyA5ZCO55qE6K+35rGC54q25oCB77yM6Iul5pyA5ZCO6K+35rGC5pe2UE9TVO+8jOeCueWHu+WI t+aWsOaXtuS8muaPkOekuuWGjeasoeaPkOS6pOihqOWNleOAgjxicj48YnI+Jm5ic3A7IGBgYHB5 dGhvbjxicj4mbmJzcDsgQGFwcC5yb3V0ZSgnLycsIG1ldGhvZHM9WydHRVQnLCAnUE9TVCddKTxi cj4mbmJzcDsgZGVmIGluZGV4KCk6PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAj IOWIm+W7uuihqOWNleWvueixoTxicj4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgZm9y bSA9IE5hbWVGb3JtKCk8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7ICMg5Yik5pat 5piv5ZCm5piv5pyJ5pWI55qE5o+Q5LqkPGJyPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyBpZiBmb3JtLnZhbGlkYXRlX29uX3N1Ym1pdCgpOjxicj4mbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgc2Vzc2lvblsnbmFtZSddID0gZm9ybS5u YW1lLmRhdGE8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7IHJldHVybiByZWRpcmVjdCh1cmxfZm9yKCdpbmRleCcpKTxicj4mbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsgbmFtZSA9IHNlc3Npb24uZ2V0KCduYW1lJyk8YnI+Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7ICMg5Zyo5qih5p2/5paH5Lu25Lit5riy5p+T6KGo5Y2V PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyByZXR1cm4gcmVuZGVyX3RlbXBsYXRl KCdmb3JtMi5odG1sJywgZm9ybT1mb3JtLCBuYW1lPW5hbWUpPGJyPiZuYnNwOyBgYGA8YnI+PGJy Pi0g5bi46KeB5a2X5q6157G75Z6L77ya6K+36Ieq6KGM5rWL6K+VPGJyPjxicj4mbmJzcDsgfCDl rZfmrrXnsbvlnosmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsgfCDor7TmmI4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsgfDxicj4mbmJzcDsgfCAtLS0tLS0tLS0tLS0tIHwgLS0tLS0tLS0tLS0tLS0tLS0tLSB8 PGJyPiZuYnNwOyB8IFN0cmluZ0ZpZWxkJm5ic3A7Jm5ic3A7IHwg5pmu6YCa5paH5pysJm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IHw8YnI+Jm5ic3A7IHwgU3VibWl0RmllbGQmbmJz cDsmbmJzcDsgfCDmj5DkuqTmjInpkq4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsg fDxicj4mbmJzcDsgfCBQYXNzd29yZEZpZWxkIHwg5a+G5paH5paH5pysJm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7IHw8YnI+Jm5ic3A7IHwgSGlkZGVuRmllbGQmbmJzcDsmbmJzcDsg fCDpmpDol4/lrZfmrrUmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgfDxicj4mbmJz cDsgfCBSYWRpb0ZpZWxkJm5ic3A7Jm5ic3A7Jm5ic3A7IHwg5Y2V6YCJ5qGGJm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IHw8YnI+Jm5ic3A7IHwgQm9vbGVhbkZpZWxkJm5i c3A7IHwg5aSN6YCJ5qGGJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IHw8 YnI+Jm5ic3A7IHwgU2VsZWN0RmllbGQmbmJzcDsmbmJzcDsgfCDkuIvmi4nmoYYmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgfDxicj4mbmJzcDsgfCBGaWxlRmllbGQmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsgfCDmlofku7bkuIrkvKAmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsgfDxicj4mbmJzcDsgfCBUZXh0QXJlYUZpZWxkIHwg5paH5pys5Z+fJm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IHw8YnI+Jm5ic3A7IHwgSW50ZWdlckZp ZWxkJm5ic3A7IHwg5paH5pys5a2X5q6177yM5YC85Li65pW05pWwJm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IHw8YnI+Jm5ic3A7IHwg RmxvYXRGaWVsZCZuYnNwOyZuYnNwOyZuYnNwOyB8IOaWh+acrOWtl+aute+8jOWAvOS4uua1rueC ueaVsCZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyB8PGJyPiZuYnNwOyB8IERhdGVGaWVsZCZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyB8IGRhdGV0 aW1lLmRhdGXnsbvlnosmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgfDxicj4mbmJzcDsgfCBEYXRl VGltZUZpZWxkIHwgZGF0ZXRpbWUuZGF0ZXRpbWXnsbvlnosgfDxicj48YnI+LSDluLjop4Hpqozo r4HlmajvvJror7foh6rooYzmtYvor5U8YnI+PGJyPiZuYnNwOyB8IOmqjOivgeWZqCZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyB8IOivtOaYjiZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyB8PGJyPiZuYnNwOyB8 IC0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0tLS0tLS0gfDxicj4mbmJzcDsgfCBMZW5ndGgm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgfCDop4TlrprlrZfnrKbplb/luqYm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsgfDxicj4mbmJzcDsgfCBEYXRhUmVxdWlyZWQgfCDnoa7kv53l rZfmrrXmnInlgLwo5o+Q56S65L+h5oGv5LiO5omA5YaZ55qE5LiN5LiA6Ie0KSB8PGJyPiZuYnNw OyB8IEVtYWlsJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IHwg6YKu 566x5qC85byPJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IHw8YnI+Jm5ic3A7IHwg SVBBZGRyZXNzJm5ic3A7Jm5ic3A7Jm5ic3A7IHwgSVDlnLDlnYAmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsgfDxicj4mbmJzcDsgfCBOdW1iZXJSYW5nZSZuYnNwOyB8IOaVsOWAvOea hOiMg+WbtCZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyB8PGJyPiZuYnNwOyB8IFVSTCZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyB8IOe7n+S4 gOi1hOa6kOWumuS9jeespuagvOW8jyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyB8PGJyPiZuYnNwOyB8IEVxdWFsVG8mbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsgfCDpqozor4HkuKTkuKrlrZfmrrXnmoTkuIDoh7TmgKcmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgfDxicj4m bmJzcDsgfCBSZWdleHAmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgfCDmraPl iJnmoKHpqowmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgfDxicj48YnI+LSDoh6rl rprkuYnlrZfmrrXpqozor4Hlh73mlbA8YnI+PGJyPiZuYnNwOyBgYGBweXRob248YnI+Jm5ic3A7 ICMg5Yib5bu66KGo5Y2V57G7PGJyPiZuYnNwOyBjbGFzcyBOYW1lRm9ybShGbGFza0Zvcm0pOjxi cj4mbmJzcDsmbmJzcDsgJm5ic3A7Jm5ic3A7Jm5ic3A7ICZuYnNwO+OAguOAguOAgjxicj4mbmJz cDsgJm5ic3A7Jm5ic3A7ICZuYnNwOyMg5a2X5q615qCh6aqM5Ye95pWw77yaJ3ZhbGlkYXRlX+Wt l+auteWQjSc8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IGRlZiB2YWxpZGF0ZV9u YW1lKHNlbGYsIGZpZWxkKTo8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7IGlmIGxlbihmaWVsZC5kYXRhKSAmbHQ7IDY6PGJyPiZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyByYWlzZSBWYWxpZGF0aW9uRXJyb3IoJ+eUqOaIt+WQjeS4jeiDveWwkeS6 jjbkuKrlrZfnrKYnKTxicj4mbmJzcDsgYGBgPGJyPjxicj4jIyMg5raI5oGv6Zeq54OBPGJyPjxi cj4tIOivtOaYju+8mjxicj48YnI+Jm5ic3A7IOW9k+eUqOaIt+WPkeWHuuivt+axguWQju+8jOeK tuaAgeWPkeeUn+S6huaUueWPmO+8jOmcgOimgeezu+e7n+e7meWHuuitpuWRiuaPkOekuuetieS/ oeaBr+aXtu+8jOmAmuW4uOmDveaYr+W8ueWHuuS4gOadoea2iOaBr++8jOaMh+ekuueUqOaIt+S4 i+S4gOatpeeahOaTjeS9nO+8jOeUqOaIt+WPr+S7peaJi+WKqOWFs+mXreaIluiHquWKqOa2iOWk se+8jOaVtOS4qui/h+eoi+S4jeS8muW9seWTjemhtemdoueahOato+W4uOaYvuekuuOAgjxicj48 YnI+LSDkvb/nlKjvvJo8YnI+PGJyPiZuYnNwOyAtIOWcqOmcgOimgemXqueDgea2iOaBr+aXtu+8 jOS9v+eUqGBmbGFzaGDlh73mlbDkv53lrZjpl6rng4Hmtojmga88YnI+PGJyPiZuYnNwOyBgYGBw eXRob248YnI+Jm5ic3A7IEBhcHAucm91dGUoJy8nLCBtZXRob2RzPVsnR0VUJywgJ1BPU1QnXSk8 YnI+Jm5ic3A7IGRlZiBpbmRleCgpOjxicj4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsg IyDliJvlu7rooajljZXlr7nosaE8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IGZv cm0gPSBOYW1lRm9ybSgpPGJyPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAjIOWIpOaW reaYr+WQpuaYr+acieaViOeahOaPkOS6pDxicj4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsgaWYgZm9ybS52YWxpZGF0ZV9vbl9zdWJtaXQoKTo8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7ICMg5pyA5ZCO5LiA5qyh5o+Q5Lqk55qE 5ZCN5a2XPGJyPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyBsYXN0X25hbWUgPSBzZXNzaW9uLmdldCgnbmFtZScpPGJyPiZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAjIOWmguaenOWtmOWcqOac gOWQjuaPkOS6pOeahOWQjeWtl++8jOS4lOacgOWQjuaPkOS6pOeahOWQjeWtl+S4juS5i+WJjeS/ neWtmOeahOWQjeWtl+S4jeebuOWQjOaXtjxicj4mbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgaWYgbGFzdF9uYW1lIGFuZCBsYXN0X25hbWUgIT0g Zm9ybS5uYW1lLmRhdGE6PGJyPiZuYnNwOyZuYnN

以上是关于Flask:03-你离最美的web只差一个:bootstrap与表单的主要内容,如果未能解决你的问题,请参考以下文章

你离升职加薪只差一个沟通的距离

你离心想事成只差一个计划 | 进击

你离高薪 offer 只差一个接口自动化入门,我是认真的

开源|Davinci用户体验:你离数据可视精美大屏只差一个Davinci!

抖音推荐算法深度解析,你离上热门只差......

你离BAT之间,只差这一套Java面试题。