Flask框架及jinja2引擎模版

什么是Flask框架?

Flask是一个使用 Python 编写的轻量级 Web 应用框架。

导入Flask类;
from flask import Flask
#实例化一个Flask对象,
#     __name__是模块的名称或者包的名称
#     作用: 根据这个参数确定flask应用的路径, 从而快速查找模板和html文件的默认路径;
#     模块就是python文件; 包就是目录(跟普通目录多加一个__init__.py);
app = Flask(__name__)
#基本路由:通过路由绑定一个视图函数
#   @app.route('/'): 告诉Flask哪个URL才能出发对应的函数, 又称为路由;
#   对应定义了一个视图函数, 也就是返回给用户浏览器显示的内容;
@app.route('/')
def index():
    return '<h1>hello world</h1>'
@app.route('/login/')
def login():
    return 'login'
#  运行Flask应用, 可以指定ip和端口;
# '0.0.0.0' 所有的IP都可以访问到;
app.run('0.0.0.0',9000)

在这里插入图片描述

路由与变量规则

常见路由的规则

  1. url的一部分可以标记为变量<变量名>
  2. flask中路由里面的变量常见类型:
    int, string, float, path, uuid
from flask import Flask,request
app = Flask(__name__)
@app.route('/<int:id>/coomments/')
def comment1(id):
    return 'Comment id:%s' %(id)
@app.route('/welcome/<string:user>/')
def welcome(user):
    return user+'用户欢迎您!'
# 特殊的url地址: http://www.baidu.com/query?id=123&name=cooffee
@app.route('/query')
def query():
    id = request.args.get('id')
    name = request.args.get('name')
    return 'id:%s,name:%s' %(id,name)
app.run()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

url构建反向URL

from flask import Flask,request,url_for
app = Flask(__name__)
@app.route('/welcome/<string:user>/')
def welcome(user):
    return user + "用户欢迎您"
@app.route('/path/')
def path():
    print(request.headers)
    # 查看默认url地址的请求方法;
    # methods is a list of methods this rule should be limited
    # to (``GET``, ``POST`` etc.).  By default a rule
    # just listens for ``GET``
    print(request.method)
    # url_for: 根据函数名, 反向生成url地址
    print("用户正在访问url地址:%s" %(url_for(endpoint='welcome',user='cooffee')))
    return "用户正在访问url地址:%s" %(url_for(endpoint='welcome',user='cooffee'))
app.run(port=9001)

在这里插入图片描述

常见http方法之post与get

1.常见HTTP请求方法:
GET: 1). 获取信息 2). 提交的信息会展示在url: http://www.floating.org/login?user=cooffee&passwd=cooffee
POST:1). 提交信息, 不在url里面展示, 有利于数据的安全性;
2.默认路由接受的请求方法为get
3.如何指定接收多个HTTP请求方法app.route(’/login/’, methods=[‘GET’, ‘POST’])
4.如何判断用户请求的HTTP方法request.method
5.如何获取用户POST请求提交的表单数据request.form[‘user’]
6.模板渲染(jinja2):
why? python中生成html不易修改与维护, 所以将html的内容独立到templates目录中;
how?
1). 去当前项目目录下寻找templtes是否存在?再去判断templates目录下是否有login.html文件?
2). 读取这个login.html文件的内容, 作为render_template的返回值;
3). 最终返回给用户浏览器;
render_template(‘login.html’)
7.重定向和错误?
redirect(url_for(‘index’))
return render_template(‘login.html’, message=“用户名或者密码错误”)
注意:这需要在工程下建立static文件夹来保存css,font,img,js
建立templates文件夹来保存html页面
而run.py为主程序
在这里插入图片描述

from flask import Flask,request,render_template,redirect,url_for,abort
app = Flask(__name__)
@app.route('/')
def index():
    return render_template('index.html')
@app.route('/login/',methods=['GET','POST'])
def login():
    if request.method == 'POST':
        print(request.form)
        # 1. 如何获取到用户提交的信息呢?
        user = request.form['user']
        passwd = request.form['passwd']
        # 2. 判断用户名和密码是否正确
        if user == 'root' and passwd == 'cooffee':
        # 如果登陆成功, 跳转到主页;
            return redirect(url_for('index'))
        else:
        # 如果登陆失败, 重新登陆;
            return render_template('login.html',message='用户名或者密码错误')
    else:
    # 用户是GET请求, 返回登陆的html页面
        # 1. 读取login.html文件的内容
        # 2. 将读取的内容返回给用户界面
        return render_template('login.html')
# 404异常处理: 类似于捕获异常
@app.errorhandler(404)
def not_found(e):
    return render_template('404.html')
# 抛出异常
@app.route('/user/<int:user_id>/')
def user(user_id):
    if 0<int(user_id)<=100:
        return "欢迎访问:%s" %(user_id)
    else:
        abort(404)
app.run(port=9002)

在这里插入图片描述

什么是jinjia2模板引擎?

python的Web开发中, 业务逻辑(实质就是视图函数的内容)和页面逻辑(html
文件)分开的, 使得代码的可读性增强, 代码容易理解和维护;
模板渲染: 在html文件中,通过动态赋值 , 将重新翻译好的html文件(模板引擎生效) 返回给用户的过程。
其他的模板引擎: Mako, Template, Jinja2

jianja2的常用用法

变量显示

Jinja2变量显示语法: {{ 变量名 }}
for循环:
{% for i in li%}
{% endfor %}

if语句
{% if user == ‘root’%}
{% elif user == ‘hello’ %}
{% else %}
{% endif%}

from flask import Flask,render_template
app = Flask(__name__)
class User(object):
    def __init__(self,name,passwd):
        self.name = name
        self.passwd = passwd
    def __str__(self):
        return "<User:%s>" %(self.name)

@app.route('/')
def index1():
    name = "this is a message"
    li = [1,2,4,5]
    d = dict(a=1,b=2)
    u = User("cooffee",'passwd')
    return render_template('index1.html',
                           name=name,
                           li = li,
                           d= d,
                           u= u)
app.run(port=9003)

html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p>变量:</p>{{name}}
<p>列表:</p>{{li}}
{% for i in li %}
<br>列表元素显示:{{i}}
{% endfor %}
<p>字典:</p> {{d}}
<p>字典:</p> {{d.a}}
<p>字典:</p> {{d['b']}}
<p>对象:</p>{{u}}
<table>
    <tr>
        <th>用户名</th>
        <td>密码</td>
    </tr>
    <tr>
        <td>{{u.name}}</td>
        <td>{{u.passwd}}</td>
    </tr>
</table>
</body>
</html>

在这里插入图片描述

过滤器与自定义过滤器

什么是过滤器?
实质上就是一个转换函数/方法

import time
from flask import Flask,render_template
app = Flask(__name__)
class User(object):
    def __init__(self,name,passwd):
        self.name =name
        self.passwd = passwd
    def __str__(self):
        return "<User:%s>" %(self.name)
@app.route('/')
def index2():
    name = 'this is a message'
    li = [1,2,4,5]
    d = dict(a=1,b=2)
    lidict = [{
        'count':100,
        'price':30
    },
        {
            'count':110,
            'price':20
        }]
    u = User('cooffee','passwd')
    timestamp = time.time()
    return render_template('index2.html',
                           name=name,
                           li=li,
                           d = d,
                           u = u,
                           lidict = lidict,
                           timestamp = timestamp)
def format_data(value,format="%Y-%m-%d %H:%M:%S"):
    ttime = time.localtime(value)
    return time.strftime("%Y-%m-%d %H:%M:%S",ttime)
 #添加过滤器(函数名,过路器名)
app.add_template_filter(format_data,'format_date')

@app.route('/index3')
def index3():
    return render_template('index3.html',timestamp=time.time())
app.run(port=9004)

index2.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ timestamp }}
{{ timestamp | format_date }}
/*常见的字符串过滤器操作:*/
<ul>
    <li>{{ name | upper }}</li>
    <li>{{ name | lower }}</li>
    <li>{{ "hello" | capitalize }}</li>
    <li>{{ " hello world" | capitalize }}</li>
    <li>{{ name | reverse }}</li>
</ul>
/*常见数值操作*/
<ul>
    <!--四舍五入-->
    <li>{{ -12.9623423435 | round }}</li>
    <li>{{ -12.9623423435 | round | abs }}</li>

</ul>
/*列表常见:*/
<ul>
    <li>{{li}}</li>
    <li>{{li|first}}</li>
    <li>{{li|last}}</li>
    <li>{{li|length}}</li>
    <li>{{li|sum}}</li>
    <li>{{li|sort|reverse}}</li>
    <li>{{li|join(":")}}</li>
    <li>{{["hello","world"]|upper}}</li>
    <li>{{["hello","woRld"]|lower}}</li>
</ul>
/*列表包含字典常用操作:*/
<ul>
    {% for item in lidict | sort(attribute='price',reverse=false) %}
    {{item}}
    {% endfor %}
</ul>
</body>
</html>

在这里插入图片描述
index3.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{timestamp}}
#使用刚才自定义的fotmat_date过滤器
{{timestamp | format_date}}
</body>
</html>

在这里插入图片描述

模板的继承
模板继承语法:
    1. 如何继承某个模板?
            {% extends "模板名称" %}


    2. 如何挖坑和填坑?
    挖坑:
        {% block 名称 %}

            默认值

        {% endblock %}
    填坑:
        {% block 名称 %}

        {% endblock %}


    3. 如何调用/继承被替代的模板?
        挖坑:
        {% block 名称 %}

            默认值

        {% endblock %}


    填坑:
        {% block 名称 %}
            #如何继承挖坑时的默认值?
            {{ super() }}

            # 后面写新加的方法.
            ........
        {% endblock %}

base.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}首页{% endblock %} | cooffee</title>
    <link rel="stylesheet" href="../static/css/bootstrap.min.css">
    <link rel="stylesheet" href="../static/css/main.css">
    <script src="../static/js/bootstrap.min.js"></script>
</head>
<body>
                     <!--导航栏-->
<nav class="navbar navbar-default">
  <div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
        <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="index.html"></a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active" style="padding-bottom: 15px;"><a href="index.html">首页<span class="sr-only">(current)</span></a></li>
        <li><a href="#">国内</a></li>
          <li><a href="#">数读</a></li>
          <li><a href="#">社会</a></li>
      </ul>
      <ul class="nav navbar-nav navbar-right">
        <li><a href="/login/">登陆</a></li>
        <li><a href="signup.html">注册</a></li>
      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>
{% block content %}

{% endblock %}
<div class="footer">


        京ICP备11008151号京公网安备11010802014853


</div>

</body>
</html>

index.html:

{% extends "base.html" %}

{% block title %}
{# <!--继承挖坑时填的默认值--> #}
{{super()}}

{% endblock %}

{% block content %}
<div class="container container-fluid">
    <div class="row">
        <!--左侧导航-->
        <div class="col-xs-2">
            <div class="list-group left-side">
                <a class="list-group-item left-side-active" href="#">综合</a>
                <a class="list-group-item" href="#">电影</a>
                <a class="list-group-item" href="#">电视剧</a>
                <a class="list-group-item" href="#"> 明星</a>
                <a class="list-group-item" href="#">娱乐</a>
            </div>
        </div>

        <!--中间新闻-->
        <div class="col-xs-7">
            <div class="media">
                <div class="media-left">
                    <a href="news.html">
                        <img class="media-object news-png"
                             src="../static/img/index1.jpg"
                             alt="新闻图片"></a>
                </div>
                <div class="media-body">
                    <h4 class="media-heading"><b>2年前他为教育和高圆圆分手,今成这般,高圆圆:我有一句MMP如哽在喉</b></h4>
                    <div class="news-info">
                        <img class="news-logo" src="../static/img/u=1271327272,62771227&fm=26&gp=0.jpg">
                        <span>王花花</span>.
                        <span>25K评论</span>.
                        <span>7分钟前</span>
                    </div>
                </div>
            </div>
             <div class="media">
                <div class="media-left">
                    <a href="news.html">
                        <img class="media-object news-png"
                             src="../static/img/2.2.jpg"
                             alt="新闻图片"></a>
                </div>
                <div class="media-body">
                    <h4 class="media-heading"><b>2年前他为教育和高圆圆分手,今成这般,高圆圆:我有一句MMP如哽在喉</b></h4>
                    <div class="news-info">
                        <img class="news-logo" src="../static/img/u=1271327272,62771227&fm=26&gp=0.jpg">
                        <span>王花花</span>.
                        <span>25K评论</span>.
                        <span>7分钟前</span>
                    </div>
                </div>
            </div>

             <div class="media">
                <div class="media-left">
                    <a href="news.html">
                        <img class="media-object news-png"
                             src="../static/img/2.jpg"
                             alt="新闻图片"></a>
                </div>
                <div class="media-body">
                    <h4 class="media-heading"><b>2年前他为教育和高圆圆分手,今成这般,高圆圆:我有一句MMP如哽在喉</b></h4>
                    <div class="news-info">
                        <img class="news-logo" src="../static/img/u=1271327272,62771227&fm=26&gp=0.jpg">
                        <span>王花花</span>.
                        <span>25K评论</span>.
                        <span>7分钟前</span>
                    </div>
                </div>
            </div>

             <div class="media">
                <div class="media-left">
                    <a href="news.html">
                        <img class="media-object news-png"
                             src="../static/img/2.2.jpg"
                             alt="新闻图片"></a>
                </div>
                <div class="media-body">
                    <h4 class="media-heading"><b>2年前他为教育和高圆圆分手,今成这般,高圆圆:我有一句MMP如哽在喉</b></h4>
                    <div class="news-info">
                        <img class="news-logo" src="../static/img/u=1271327272,62771227&fm=26&gp=0.jpg">
                        <span>王花花</span>.
                        <span>25K评论</span>.
                        <span>7分钟前</span>
                    </div>
                </div>
            </div>

             <div class="media">
                <div class="media-left">
                    <a href="news.html">
                        <img class="media-object news-png"
                             src="../static/img/index1.jpg"
                             alt="新闻图片"></a>
                </div>
                <div class="media-body">
                    <h4 class="media-heading"><b>2年前他为教育和高圆圆分手,今成这般,高圆圆:我有一句MMP如哽在喉</b></h4>
                    <div class="news-info">
                        <img class="news-logo" src="../static/img/u=1271327272,62771227&fm=26&gp=0.jpg">
                        <span>王花花</span>.
                        <span>25K评论</span>.
                        <span>7分钟前</span>
                    </div>
                </div>
            </div>

             <div class="media">
                <div class="media-left">
                    <a href="news.html">
                        <img class="media-object news-png"
                             src="../static/img/2.2.jpg"
                             alt="新闻图片"></a>
                </div>
                <div class="media-body">
                    <h4 class="media-heading"><b>2年前他为教育和高圆圆分手,今成这般,高圆圆:我有一句MMP如哽在喉</b></h4>
                    <div class="news-info">
                        <img class="news-logo" src="../static/img/u=1271327272,62771227&fm=26&gp=0.jpg">
                        <span>王花花</span>.
                        <span>25K评论</span>.
                        <span>7分钟前</span>
                    </div>
                </div>
            </div>

                      <!--页角-->
            <nav aria-label="Page navigation">
                <ul class="pagination">
                    <li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">上一页</span></a>
                    </li>
                    <li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>
                    <li><a href="#">2 <span class="sr-only">(current)</span></a></li>
                    <li><a href="#">3 <span class="sr-only">(current)</span></a></li>
                    <li><a href="#">4 <span class="sr-only">(current)</span></a></li>
                    <li><a href="#">... <span class="sr-only">(current)</span></a></li>
                    <li><a href="#">10 <span class="sr-only">(current)</span></a></li>
                    <li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">下一页</span></a>
                    </li>
                </ul>
            </nav>
        </div>

        <div class="col-xs-3">
                       <!--搜索栏-->
                <div class="input-group input-info">
                  <input type="text" class="form-control" placeholder="搜一下">
                </div>
                     <!--有害信息-->
                <div class="bad-infomation">
                    <table id="bad-table">
                        <tr>
                            <td rowspan="2">
                                <img class="bad-jpg" src="../static/img/4.png">
                            </td>
                            <td id="bad-font1">有害信息举报专区</td>
                        </tr>
                        <tr>
                            <td id="bad-font2">
                                举报电话12377
                            </td>
                        </tr>
                    </table>
                </div>

                    <!--新闻推荐-->
            <div class="list-group hot-news">
                <a href="#" class="list-group-item">
                    <span style="font-size: larger"><b>24小时热闻</b></span>
                </a>
                <a href="#" class="list-group-item"><span style="font-size: large"> Lorem ipsum dolor sit amet,consectetur adipisicing</span><div class="news-info">
                        <span>25K评论</span>
                        <span>7分钟前</span></div></a>
                <a href="#" class="list-group-item"><span style="font-size: large"> Lorem ipsum dolor sit amet,consectetur adipisicing</span><div class="news-info">
                        <span>25K评论</span>
                        <span>7分钟前</span></div></a>
                <a href="#" class="list-group-item"><span style="font-size: large"> Lorem ipsum dolor sit amet,consectetur adipisicing</span><div class="news-info">
                        <span>25K评论</span>
                        <span>7分钟前</span></div></a>
                <a href="#" class="list-group-item"><span style="font-size: large"> Lorem ipsum dolor sit amet,consectetur adipisicing</span><div class="news-info">
                        <span>25K评论</span>
                        <span>7分钟前</span></div></a>
                <a href="#" class="list-group-item"><span style="font-size: large"> Lorem ipsum dolor sit amet,consectetur adipisicing</span><div class="news-info">
                        <span>25K评论</span>
                        <span>7分钟前</span></div></a>

            </div>
        </div>
    </div>
</div>
{% endblock %}

run.py:

from flask import Flask,request,render_template,redirect,url_for,abort
app = Flask(__name__)
@app.route('/')
def index():
    return render_template('index.html')
@app.route('/login/',methods=['GET','POST'])
def login():
    if request.method == 'POST':
        print(request.form)
        user = request.form['user']
        passwd = request.form['passwd']
        if user == 'root' and passwd == 'cooffee':
            return redirect(url_for('index'))
        else:
            return render_template('login.html',message='用户名或者密码错误')
    else:
        return render_template('login.html')
@app.errorhandler(404)
def not_found(e):
    return render_template('404.html')
@app.route('/user/<int:user_id>/')
def user(user_id):
    if 0<int(user_id)<=100:
        return "欢迎访问:%s" %(user_id)
    else:
        abort(404)
app.run(port=9002)

在这里插入图片描述

宏macro的使用

macro.html:
宏: 是一个函数

{% macro input(type,name,text) %}
 <div class="form-group">
        <label>{{text}}</label>
        <input name={{name}} type={{type}} class="form-control username-text">
      </div>
{% endmacro %}

login.html:

{% extends "base.html" %}

{% block title %}
登陆
{% endblock %}
{% block content %}
      <!--登陆界面-->
 <div class="container container-small login">
    <h1>登录
      <small>没有账号?<a href="signup.html">注册</a></small>
    </h1>
    <form action="/login/" method="post">
      <!--<div class="form-group">-->
        <!--<label>用户名/手机/邮箱</label>-->
        <!--<input name="user" type="text" class="form-control username-text">-->
      <!--</div>-->
      <!--<div class="form-group">-->
        <!--<label>密码</label>-->
        <!--<input name="passwd" type="password" class="form-control username-text">-->
      <!--</div>-->
        {% import 'macro.html' as macro %}

        {{macro.input('text','user','用户名/手机/邮箱')}}
        {{macro.input('password','passwd','密码')}}
      <div class="form-group">
        <button class="btn btn-primary btn-block block-sure" type="submit">登录</button>
      </div>
      <div class="form-group">
        <a href="#">忘记密码?</a>
      </div>
      {% if message %}
        <p style="color: red">{{message}}</p>
      {% endif %}
    </form>
  </div>
{% endblock %}

在这里插入图片描述

session操作

cookie: 客户端浏览器的缓存;
session: 服务端服务器的缓存;

Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,
存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的
Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,
服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。

from flask import Flask,session
import random
app = Flask(__name__)
# 设置是24位的字符, 每次运行服务器的secret_key都是不同的,
# 服务器重启后会清除上一次存储的session信息值;
app.config['SECRET_KEY'] =random._urandom(24)
# 设置session值;
@app.route("/")
def index():
    session['name']='cooffee'
    return  "hello world"
# 如何获取?
@app.route('/get/')
def get():
    return session.get('name')
 # 如何删除?
@app.route('/delete/')
def delete():
    print(session.get('name'))
    session.pop('name')
    print(session.get('name'))
    return 'delete'
app.run(port=9006)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

判断用户是否登陆的装饰器
import  functools

def is_login(f):

    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        # run函数代码里面, 如果登陆, session加入user, passwd两个key值;
        # run函数代码里面, 如果注销, session删除user, passwd两个key值;
        # 如果没有登陆成功, 则跳转到登陆界面
        if 'user' not in session:
            return  redirect('/login/')
        # 如果用户是登陆状态, 则访问哪个路由, 就执行哪个路由对应的视图函数;
        return  f(*args, **kwargs)
    return  wrapper

run.py:

import random
import functools
from flask import Flask, request, render_template, redirect, url_for, abort, session

app = Flask(__name__)
app.config['SECRET_KEY'] = random._urandom(24)
def is_login(f):
    @functools.wraps(f)
    def wrapper(*args,**kwargs):
        if 'user' not in session:
            return redirect(url_for('login'))
        return f(*args,**kwargs)
    return wrapper

#先判断是否登陆,若登陆才能进入到主页
@app.route('/')
@is_login
def index():
    return render_template('index.html')


@app.route('/login/',methods=['GET','POST'])
def login():
    if request.method == 'POST':
        print(request.form)
        user = request.form['user']
        passwd = request.form['passwd']
        if user == 'root' and passwd == 'cooffee':
        # 将用户名和密码信息存储到session中;
            session['user']=user
            session['passwd']=passwd
            # 如果登陆成功, 跳转到主页;
            return redirect(url_for('index'))
        else:
         # 如果登陆失败, 重新登陆;
            return render_template('login.html',message='用户名或者密码错误')
    else:
        # 用户是GET请求, 返回登陆的html页面
        # 1. 读取login.html文件的内容
        # 2. 将读取的内容返回给用户界面
        return render_template('login.html')
@app.errorhandler(404)
def not_found(e):
    return render_template('404.html')
@app.route('/user/<int:user_id>/')
def user(user_id):
    if 0<int(user_id)<=100:
        return "欢迎访问:%s" %(user_id)
    else:
        abort(404)
app.run(port=9002)
上传文件

实现目标: 如何将文件上传到服务器(保存在指定的文件夹)

import os
from flask import Flask,request,render_template
app = Flask(__name__)
@app.route('/upload/',methods=['GET','POST'])
def upload():
    if request.method == 'POST':
        # 获取到用户上传的文件对象
        f = request.files['faceImg']
        # 获取当前项目所在目录位置;
        basepath = os.path.dirname(__file__)
        # 拼接路径, 存储文件到static/face/xxxx
        fiename = os.path.join(basepath,'static/face',f.filename)
        # 保存文件
        f.save(fiename)
        return render_template('upload.html',message="上传成功")
    else:
        return render_template('upload.html')
app.run(port=9007)

upload.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/upload/" method="post" enctype="multipart/form-data">
        <input type="file" name="faceImg">
        <input type="submit" value="提交">

        {%  if message %}
        <p style="color: red">{{ message }}</p>

        {% endif %}
    </form>
</body>
</html>

在这里插入图片描述
在这里插入图片描述

表单处理flask-wtf
  1. 为什么使用Flask-WTF?
    request对象公开了所有客户端发送的请求信息。特别是request.form可以访问POST请求提交的表单数据。
    尽管Flask的request对象提供的支持足以处理web表单,但依然有许多任务会变得单调且重复。
    表单的HTML代码生成和验证提交的表单数据就是两个很好的例子。
    优势:
    Flask-WTF扩展使得处理web表单能获得更愉快的体验。该扩展是一个封装了与框架无关的WTForms包的Flask集成。

  2. 什么是表单处理?

    在网页中,为了和用户进行信息交互总是不得不出现一些表单。
    flask设计了WTForm表单库来使flask可以更加简便地管理操作表单数据。
    WTForm中最重要的几个概念如下:

    1). Form类,开发者自定义的表单必须继承自Form类或者其子类。
    Form类最主要的功能是通过其所包含的Field类提供对表单内数据的快捷访问方式。

    2). 各种Field类,即字段。一般而言每个Field类都对应一个input的HTML标签。
    比如WTForm自带的一些Field类比如BooleanField就对应,
    SubmitField就对应等等。

    3). Validator类。这个类用于验证用户输入的数据的合法性。
    比如Length验证器可以用于验证输入数据的长度,
    FileAllowed验证上传文件的类型等等。

    另外,flask为了防范csfr(cross-site request forgery)攻击,
    默认在使用flask-wtf之前要求app一定要设置过secret_key。
    最简单地可以通过app.config[‘SECRET_KEY’] = 'xxxx’来配置。

  3. 常见的Field类

    PasswordField   密码字段,自动将输入转化为小黑点

    DateField   文本字段,格式要求为datetime.date一样

    IntergerField   文本字段,格式要求是整数

    DecimalField   文本字段,格式要求和decimal.Decimal一样

    FloatField   文本字段,值是浮点数

    BooleanField   复选框,值为True或者False

    RadioField   一组单选框

    SelectField   下拉列表,需要注意一下的是choices参数确定了下拉选项,
    但是和HTML中的 标签一样,其是一个tuple组成的列表,
    可以认为每个tuple的第一项是选项的真正的值,而第二项是alias。

    MultipleSelectField  可选多个值的下拉列表

  4. Validator是验证函数: 
    Validator是验证函数,把一个字段绑定某个验证函数之后,flask会在接收表单中的数据之前对数据做一个验证,
    如果验证成功才会接收数据。验证函数Validator如下,具体的validator可能需要的参数不太一样,这里只给出
    一些常用的,更多详细的用法可以参见wtforms/validators.py文件的源码,参看每一个validator类需要哪些参数:

    *基本上每一个validator都有message参数,指出当输入数据不符合validator要求时显示什么信息。

    Email  验证电子邮件地址的合法性,要求正则模式是.+@([.@][^@]+)$

    EqualTo  比较两个字段的值,通常用于输入两次密码等场景,可写参数fieldname,不过注意其是一个字符串变量,指向同表单中的另一个字段的字段名

    IPAddress  验证IPv4地址,参数默认ipv4=True,ipv6=False。如果想要验证ipv6可以设置这两个参数反过来。

    Length  验证输入的字符串的长度,可以有min,max两个参数指出要设置的长度下限和上限,注意参数类型是字符串,不是INT!!

    NumberRange  验证输入数字是否在范围内,可以有min和max两个参数指出数字上限下限,注意参数类型是字符串,不是INT!!然后在这个validator的message参数里可以设置%(min)s和%(max)s两个格式化部分,来告诉前端这个范围到底是多少。其他validator也有这种类似的小技巧,可以参看源码。

    Optional  无输入值时跳过同字段的其他验证函数

    Required  必填字段

    Regexp  用正则表达式验证值,参数regex=‘正则模式’

    URL  验证URL,要求正则模式是[a-z]+://(?P<host>[/:]+)(?P:[0-9]+)?(?P /.*)?$

    AnyOf  确保值在可选值列表中。参数是values(一个可选值的列表)。特别提下,和SelectField进行配合使用时,不知道为什么SelectField的choices中项的值不能是数字。。否则AnyOf的values参数中即使有相关数字也无法识别出当前选项是合法选项。我怀疑NoneOf可能也是一样的套路。

    NoneOf  确保值不在可选值列表中
    forms.py:

from flask_wtf import FlaskForm
from flask_wtf.file import FileRequired, FileAllowed
from wtforms import StringField, PasswordField, SubmitField, FileField
from wtforms.validators import DataRequired, Length

class LoginForm(FlaskForm):
    name = StringField(
        label="用户名/邮箱/手机号",
        validators=[
             DataRequired(message=u"请输入用户名"),
            Length(3, 10, message=u"长度不符"),
        ]

    )
    passwd = PasswordField(
        label="密码",
        validators=[
             DataRequired(message=u"输入密码"),
            Length(3, 10,message=u"长度不符")
        ] )

    file = FileField(
        label="简历",
        validators=[
            FileRequired(),
            FileAllowed(['pdf', 'txt'], 'pdf 能被接收')
        ]
    )

run.py:

import random
from flask import Flask, redirect, render_template, flash
from _Flask框架.forms import LoginForm
from flask_bootstrap import  Bootstrap
app = Flask(__name__)
bootstrap = Bootstrap(app)
app.config['SECRET_KEY'] =  random._urandom(24)
@app.route('/success/')
def success():
    return  "success"

@app.route('/login/', methods=('GET', 'POST'))
def submit():
    # 实例化表单对象;
    form = LoginForm()
    if form.validate_on_submit():
        print(form.data)
        flash(form.name.data+'|'+form.passwd.data)
        return redirect('/success/')
    return render_template('wtflogin.html', form=form)
app.run(port=8000)

wtflogin.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form method="POST" action="/login/">
    {{form.hidden_tag()}}
    <p>{{ form.name.label }} {{ form.name }}
        {%for e in form.name.errors%}
        <span style="color: red">{{e}}</span>
        {% endfor %}
    </p>
    <p>{{ form.passwd.label }} {{ form.passwd }}
        {%for j in form.name.errors%}
        <span style="color: red">{{j}}</span>
        {%endfor%}
    </p>
    <p>{{ form.file }}</p>
    <input type="submit" value="Go">
</form>
</body>
</html>

在这里插入图片描述

用flask框架及jinja2引擎优化new项目

目录结构

在这里插入图片描述

templates

base.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}首页{% endblock %} | cooffee</title>
    <link rel="stylesheet" href="../static/css/bootstrap.min.css">
    <link rel="stylesheet" href="../static/css/main.css">
    <script src="../static/js/bootstrap.min.js"></script>
</head>
<body>
                     <!--导航栏-->
<nav class="navbar navbar-default">
  <div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
        <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="index.html"></a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active" style="padding-bottom: 15px;"><a href="index.html">首页<span class="sr-only">(current)</span></a></li>
        <li><a href="#">国内</a></li>
          <li><a href="#">数读</a></li>
          <li><a href="#">社会</a></li>
          <li><a href="/sysinfo/">系统信息</a></li>
          <li><a href="#">登陆用户</a></li>
      </ul>
      <ul class="nav navbar-nav navbar-right">
          {% if 'user' in session %}
           <!--<li><a><span class="glyphicon glyphicon-user"></span></a></li>-->
           <li><a href="#">{{session.user}}</a></li>
           <li><a href="/logout/">注销</a></li>
          {% else %}
           <li><a href="/login/">登陆</a></li>
           <li><a href="/register/">注册</a></li>
          {% endif %}
      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>
{% block content %}

{% endblock %}
<div class="footer">

        京ICP备11008151号京公网安备11010802014853

</div>

</body>
</html>
index.html:
{% extends "base.html" %}

{% block title %}

{{super()}}

{% endblock %}

{% block content %}
<div class="container container-fluid">
    <div class="row">
        <!--左侧导航-->
        <div class="col-xs-2">
            <div class="list-group left-side">
                <a class="list-group-item left-side-active" href="#">综合</a>
                <a class="list-group-item" href="#">电影</a>
                <a class="list-group-item" href="#">电视剧</a>
                <a class="list-group-item" href="#"> 明星</a>
                <a class="list-group-item" href="#">娱乐</a>
            </div>
        </div>

        <!--中间新闻-->
        <div class="col-xs-7">
            <div class="media">
                <div class="media-left">
                    <a href="news.html">
                        <img class="media-object news-png"
                             src="../static/img/index1.jpg"
                             alt="新闻图片"></a>
                </div>
                <div class="media-body">
                    <h4 class="media-heading"><b>2年前他为教育和高圆圆分手,今成这般,高圆圆:我有一句MMP如哽在喉</b></h4>
                    <div class="news-info">
                        <img class="news-logo" src="../static/img/u=1271327272,62771227&fm=26&gp=0.jpg">
                        <span>王花花</span>.
                        <span>25K评论</span>.
                        <span>7分钟前</span>
                    </div>
                </div>
            </div>
             <div class="media">
                <div class="media-left">
                    <a href="news.html">
                        <img class="media-object news-png"
                             src="../static/img/2.2.jpg"
                             alt="新闻图片"></a>
                </div>
                <div class="media-body">
                    <h4 class="media-heading"><b>2年前他为教育和高圆圆分手,今成这般,高圆圆:我有一句MMP如哽在喉</b></h4>
                    <div class="news-info">
                        <img class="news-logo" src="../static/img/u=1271327272,62771227&fm=26&gp=0.jpg">
                        <span>王花花</span>.
                        <span>25K评论</span>.
                        <span>7分钟前</span>
                    </div>
                </div>
            </div>

             <div class="media">
                <div class="media-left">
                    <a href="news.html">
                        <img class="media-object news-png"
                             src="../static/img/2.jpg"
                             alt="新闻图片"></a>
                </div>
                <div class="media-body">
                    <h4 class="media-heading"><b>2年前他为教育和高圆圆分手,今成这般,高圆圆:我有一句MMP如哽在喉</b></h4>
                    <div class="news-info">
                        <img class="news-logo" src="../static/img/u=1271327272,62771227&fm=26&gp=0.jpg">
                        <span>王花花</span>.
                        <span>25K评论</span>.
                        <span>7分钟前</span>
                    </div>
                </div>
            </div>

             <div class="media">
                <div class="media-left">
                    <a href="news.html">
                        <img class="media-object news-png"
                             src="../static/img/2.2.jpg"
                             alt="新闻图片"></a>
                </div>
                <div class="media-body">
                    <h4 class="media-heading"><b>2年前他为教育和高圆圆分手,今成这般,高圆圆:我有一句MMP如哽在喉</b></h4>
                    <div class="news-info">
                        <img class="news-logo" src="../static/img/u=1271327272,62771227&fm=26&gp=0.jpg">
                        <span>王花花</span>.
                        <span>25K评论</span>.
                        <span>7分钟前</span>
                    </div>
                </div>
            </div>

             <div class="media">
                <div class="media-left">
                    <a href="news.html">
                        <img class="media-object news-png"
                             src="../static/img/index1.jpg"
                             alt="新闻图片"></a>
                </div>
                <div class="media-body">
                    <h4 class="media-heading"><b>2年前他为教育和高圆圆分手,今成这般,高圆圆:我有一句MMP如哽在喉</b></h4>
                    <div class="news-info">
                        <img class="news-logo" src="../static/img/u=1271327272,62771227&fm=26&gp=0.jpg">
                        <span>王花花</span>.
                        <span>25K评论</span>.
                        <span>7分钟前</span>
                    </div>
                </div>
            </div>

             <div class="media">
                <div class="media-left">
                    <a href="news.html">
                        <img class="media-object news-png"
                             src="../static/img/2.2.jpg"
                             alt="新闻图片"></a>
                </div>
                <div class="media-body">
                    <h4 class="media-heading"><b>2年前他为教育和高圆圆分手,今成这般,高圆圆:我有一句MMP如哽在喉</b></h4>
                    <div class="news-info">
                        <img class="news-logo" src="../static/img/u=1271327272,62771227&fm=26&gp=0.jpg">
                        <span>王花花</span>.
                        <span>25K评论</span>.
                        <span>7分钟前</span>
                    </div>
                </div>
            </div>

                      <!--页角-->
            <nav aria-label="Page navigation">
                <ul class="pagination">
                    <li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">上一页</span></a>
                    </li>
                    <li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>
                    <li><a href="#">2 <span class="sr-only">(current)</span></a></li>
                    <li><a href="#">3 <span class="sr-only">(current)</span></a></li>
                    <li><a href="#">4 <span class="sr-only">(current)</span></a></li>
                    <li><a href="#">... <span class="sr-only">(current)</span></a></li>
                    <li><a href="#">10 <span class="sr-only">(current)</span></a></li>
                    <li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">下一页</span></a>
                    </li>
                </ul>
            </nav>
        </div>

        <div class="col-xs-3">
                       <!--搜索栏-->
                <div class="input-group input-info">
                  <input type="text" class="form-control" placeholder="搜一下">
                </div>
                     <!--有害信息-->
                <div class="bad-infomation">
                    <table id="bad-table">
                        <tr>
                            <td rowspan="2">
                                <img class="bad-jpg" src="../static/img/4.png">
                            </td>
                            <td id="bad-font1">有害信息举报专区</td>
                        </tr>
                        <tr>
                            <td id="bad-font2">
                                举报电话12377
                            </td>
                        </tr>
                    </table>
                </div>

                    <!--新闻推荐-->
            <div class="list-group hot-news">
                <a href="#" class="list-group-item">
                    <span style="font-size: larger"><b>24小时热闻</b></span>
                </a>
                <a href="#" class="list-group-item"><span style="font-size: large"> Lorem ipsum dolor sit amet,consectetur adipisicing</span><div class="news-info">
                        <span>25K评论</span>
                        <span>7分钟前</span></div></a>
                <a href="#" class="list-group-item"><span style="font-size: large"> Lorem ipsum dolor sit amet,consectetur adipisicing</span><div class="news-info">
                        <span>25K评论</span>
                        <span>7分钟前</span></div></a>
                <a href="#" class="list-group-item"><span style="font-size: large"> Lorem ipsum dolor sit amet,consectetur adipisicing</span><div class="news-info">
                        <span>25K评论</span>
                        <span>7分钟前</span></div></a>
                <a href="#" class="list-group-item"><span style="font-size: large"> Lorem ipsum dolor sit amet,consectetur adipisicing</span><div class="news-info">
                        <span>25K评论</span>
                        <span>7分钟前</span></div></a>
                <a href="#" class="list-group-item"><span style="font-size: large"> Lorem ipsum dolor sit amet,consectetur adipisicing</span><div class="news-info">
                        <span>25K评论</span>
                        <span>7分钟前</span></div></a>

            </div>
        </div>
    </div>
</div>
{% endblock %}

在这里插入图片描述

login.html:
{% extends "base.html" %}

{% block title %}
登陆
{% endblock %}
{% block content %}
      <!--登陆界面-->
 <div class="container container-small login">
    <h1>登录
      <small>没有账号?<a href="/register/">注册</a></small>
    </h1>
    <form action="/login/" method="post">
      <!--<div class="form-group">-->
        <!--<label>用户名/手机/邮箱</label>-->
        <!--<input name="user" type="text" class="form-control username-text">-->
      <!--</div>-->
      <!--<div class="form-group">-->
        <!--<label>密码</label>-->
        <!--<input name="passwd" type="password" class="form-control username-text">-->
      <!--</div>-->
        {% import 'macro.html' as macro %}

        {{macro.input('text','user','用户名/手机/邮箱')}}
        {{macro.input('password','passwd','密码')}}
      <div class="form-group">
        <button class="btn btn-primary btn-block block-sure" type="submit">登录</button>
      </div>
      <div class="form-group">
        <a href="#">忘记密码?</a>
      </div>
      {% if message %}
        <p style="color: red">{{message}}</p>
      {% endif %}
    </form>
  </div>
{% endblock %}

在这里插入图片描述
在这里插入图片描述

singnup.html:
{% extends "base.html" %}

{% block title %}
注册
{% endblock %}
{% block content %}
            <!--注册界面-->
<div class="container container-small login">
    <h1>注册
      <small>没有账号?<a href="/register/">注册</a></small>
    </h1>
    <form action="/register/" method="post">
      {% import 'macro.html' as macro %}

        {{macro.input('text','user','用户名/手机/邮箱')}}
        {{macro.input('password','passwd','密码')}}
      <!--<div class="form-group">-->
        <!--<label>手机</label>-->
        <!--<input type="text" class="form-control username-text">-->
      <!--</div>-->
      <!--&lt;!&ndash;<div class="form-group username-text">&ndash;&gt;-->
        <!--&lt;!&ndash;<label>验证码</label>&ndash;&gt;-->
        <!--&lt;!&ndash;&lt;!&ndash;<div class="input-group">&ndash;&gt;&ndash;&gt;-->
          <!--&lt;!&ndash;&lt;!&ndash;<input type="text" class="form-control">&ndash;&gt;&ndash;&gt;-->
          <!--&lt;!&ndash;&lt;!&ndash;<div class="input-group-btn">&ndash;&gt;&ndash;&gt;-->
            <!--&lt;!&ndash;&lt;!&ndash;<div class="btn btn-default">获取验证码</div>&ndash;&gt;&ndash;&gt;-->
          <!--&lt;!&ndash;&lt;!&ndash;</div>&ndash;&gt;&ndash;&gt;-->
        <!--&lt;!&ndash;&lt;!&ndash;</div>&ndash;&gt;&ndash;&gt;-->
      <!--&lt;!&ndash;</div>&ndash;&gt;-->
      <!--<div class="form-group">-->
        <!--<label>密码</label>-->
        <!--<input type="password" class="form-control username-text">-->
      <!--</div>-->
      <div class="form-group">
        <button class="btn btn-primary btn-block block-sure" type="submit">注册</button>
      </div>
      <div class="form-group">
        注册咖啡或浮云即代表您同意<a href="#">咖啡或浮云服务条款</a>
      </div>
      {% if message %}
        <p style="color: red">{{message}}</p>
      {% endif %}
    </form>
  </div>
{% endblock %}

在这里插入图片描述

macro.html:
{% macro input(type,name,text) %}
 <div class="form-group">
        <label>{{text}}</label>
        <input name={{name}} type={{type}} class="form-control username-text">
      </div>
{% endmacro %}
sysinfo.html:
{% extends 'base.html' %}


{% block title %} 系统信息 {% endblock %}


{% block content %}



{#    表格内容----bootstrap #}
<table class="table table-striped" style="width: 50%; margin: auto " >
    <tr>
        <td><b style="font-size: large">系统信息</b></td>
        <td></td>
    </tr>
    <tr>
        <td>主机名</td>
        <td>{{ hostname }}</td>
    </tr>
    <tr>
        <td>内核名称</td>
        <td>{{ sysname }}</td>
    </tr>
    <tr>
        <td>发行版本号</td>
        <td>{{ release }}</td>
    </tr>
    <tr>
        <td>内核版本</td>
        <td>{{ version}}</td>
    </tr>
    <tr>
        <td>系统构架</td>
        <td>{{ machine }}</td>
    </tr>
    <tr>
        <td>现在时间</td>
        <td>{{ now_time }}</td>
    </tr>
    <tr>
        <td>开机时间</td>
        <td>{{ boot_time }}</td>
    </tr>
    <tr>
        <td>运行时间</td>
        <td>{{ delta_time }}</td>
    </tr>
</table>

{% endblock %}

在这里插入图片描述

404.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h2 style="color: red;">404: 页面未找到</h2>

</body>
</html>

程序

models.py:

连接数据库

import pymysql
conn = pymysql.connect(
    host='172.25.254.78',
    user='cooffee',
    password='cooffee',
    charset='utf8',
    db='cooffee'
    )

cur = conn.cursor()
def isUserExist(username):
    sqli = "select * from flaskdata where name='%s'" %(username)
    res = cur.execute(sqli)
    if res == 0:
        return False
    else:
        return True
def isPasswdOk(username,passwd):
    sqli = sqli = "select * from flaskdata where name='%s' and passwd='%s'" %(username, passwd)
    res = cur.execute(sqli)
    if res == 0:
        return False
    else:
        return True

def addUser(username,passwd):
    sqli = "insert into flaskdata (name, passwd) values('%s', '%s')" %(username, passwd)
    try:
        res= cur.execute(sqli)
        conn.commit()
    except Exception as e:
        conn.rollback()
        return e
if __name__ == "__main__":
    addUser('root','root')
    print(isUserExist('root'))
    print(isPasswdOk('root','root'))

在这里插入图片描述

run.py:
import random
import functools

import os
from datetime import datetime

import psutil as psutil
from flask import Flask, request, render_template, redirect, url_for, abort, session
from models import isPasswdOk, isUserExist, addUser
app = Flask(__name__)
app.config['SECRET_KEY'] = random._urandom(24)
def is_login(f):
    """判断用户是否登陆的装饰器"""
    @functools.wraps(f)
    def wrapper(*args,**kwargs):
     # run函数代码里面, 如果登陆, session加入user, passwd两个key值;
        # run函数代码里面, 如果注销, session删除user, passwd两个key值;
        # 如果没有登陆成功, 则跳转到登陆界面
        if 'user' not in session:
            return redirect(url_for('login'))
            # 如果用户是登陆状态, 则访问哪个路由, 就执行哪个路由对应的视图函数;
        return f(*args,**kwargs)
    return wrapper

# 用户主页
@app.route('/')
def index():
    return render_template('index.html')

# 用户登陆按钮
@app.route('/login/',methods=['GET','POST'])
def login():
    if request.method == 'POST':
        print(request.form)
        user = request.form['user']
        passwd = request.form['passwd']
        if isPasswdOk(user,passwd):
        # 将用户名和密码信息存储到session中;
            session['user']=user
            session['passwd']=passwd
            return redirect(url_for('index'))
        else:
            return render_template('login.html',message='用户名或者密码错误')
    else:
        return render_template('login.html')
# 用户注销
@app.route('/logout/')
def logout():
    session.pop('user',None)
    session.pop('passwd',None)
    return redirect(url_for('index'))
# 用户注册
@app.route('/register/',methods=['GET','POST'])
def register():
    if request.method == 'POST':
        user = request.form['user']
        passwd = request.form['passwd']
        if isUserExist(user):
            message = "用户已经存在"
            return render_template('signup.html',message=message)
        else:
            addUser(user,passwd)
            return redirect(url_for('login'))
    else:
        return render_template('signup.html')

@app.route('/sysinfo/')
@is_login
def sysinfo():
    info = os.uname()
    boot_time = psutil.boot_time()
    boot_time = datetime.fromtimestamp(boot_time)
    now_time = datetime.now()
    delta_time = now_time - boot_time
    delta_time = str(delta_time).split('.')[0]
    return render_template('sysinfo.html',
                           hostname=info.nodename,
                           sysname=info.sysname,
                           release=info.release,
                           version= info.version,
                           machine=info.machine,
                           now_time=str(now_time).split('.')[0],
                           boot_time=boot_time,
                           delta_time=delta_time
                           )
# 404异常处理: 类似于捕获异常
@app.errorhandler(404)
def not_found(e):
    return render_template('404.html')

app.run(port=9002)
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页