• Flask 框架基础知识笔记


    Flask 基础

    ◆CheckBox 复选框◆

    HTML index.html

    <body>
        <form action="/" method="post">
            <div class="MyDiv">
                <label>
                    <input type="checkbox" name="s_option" value="basketball" > 篮球
                </label>
                <label>
                    <input type="checkbox" name="s_option" value="football" > 足球
                </label>
                <label>
                    <input type="checkbox" name="s_option" value="badminton" > 羽毛球
                </label>
            </div>
            <input type="submit" value="发送"/>
        </form>
    </body>
    </html>
    

    后台 app.py

    from flask import Flask,render_template,request
    
    app = Flask(__name__)
    
    @app.route("/",methods=['POST','GET'])
    def index():
        if request.method == "POST":
            data = request.values.getlist("s_option")
            print("您的选择内容是: %s" %data)
        return render_template("index.html")
    
    if __name__ == '__main__':
        app.run()
    

    ◆Select 选择框◆

    HTML index.html

    <body>
        <form action="/" method="post">
            <select name="MySelect">
                     <option selected="selected">--请选择厂家--</option>
                     <option >惠普</option>
                     <option >华为</option>
                     <option >戴尔</option>
            </select>
            <input type="submit" value="发送"/>
        </form>
    </body>
    

    后台 app.py

    from flask import Flask,render_template,request
    
    app = Flask(__name__)
    
    @app.route("/",methods=['POST','GET'])
    def index():
        if request.method == "POST":
            data = request.values.get("MySelect")
            print("您的选择内容是: %s" %data)
        return render_template("index.html")
    
    if __name__ == '__main__':
        app.run()
    

    Ajax 发送数据◆

    HTML页面发送数据,后端接收并返回数据

    HTML index.html

    <body>
        <input type="button" class="MyButton" value="发送数据" onclick="SendAjax()">
    
        <script src="https://code.jquery.com/jquery-3.4.1.min.js" type="text/javascript"></script>
        <script type="text/javascript">
            function SendAjax(){
                $.ajax({
                    url:"/dataFromAjax",
                    contentType: "POST",
                    data:{"MyData": "hello lyshark"},
                    success:function(data){
                        alert("返回数据:" + data);
                    },
                    error:function(){
                        alert("执行失败了...")
                    }
                });
            }
        </script>
    </body>
    

    后台 app.py

    from flask import Flask,render_template,request
    from flask import jsonify
    
    app = Flask(__name__)
    
    @app.route("/")
    def index():
        return render_template("index.html")
    
    @app.route("/dataFromAjax")
    def recv():
        data = request.args.get("MyData")
        print("收到客户端数据: %s"%data)
        return "通信成功..."
    
    if __name__ == '__main__':
        app.run()
    

    Ajax 获取数据◆

    后端发送JSON数据,HTML页面接收数据并显示出来.

    HTML index.html

    <body>
        <input type="button" class="MyButton" value="接收数据" onclick="GetAjax()">
    
        <script src="https://code.jquery.com/jquery-3.4.1.min.js" type="text/javascript"></script>
        <script type="text/javascript">
            function GetAjax(){
                $.ajax({
                    url:"/dataFromAjax",
                    contentType: "GET",
                    success:function(data){
                        alert("姓名: " + data.name + "年龄: " + data.age);
                    },
                    error:function(){
                        alert("执行失败了...")
                    }
                });
            }
        </script>
    </body>
    

    后台 app.py

    from flask import Flask,render_template,request
    from flask import jsonify
    
    app = Flask(__name__)
    
    @app.route("/")
    def index():
        return render_template("index.html")
    
    @app.route("/dataFromAjax",methods=["GET","POST"])
    def set():
        data = {"name":"lyshark","age":"23"}
        return jsonify(data)
    
    	# info = dict()    //另一种组装发送数据的方法
    	# info['name'] = "lyshark"
    	# info['age'] = 22
    	# return jsonify(info)
    
    if __name__ == '__main__':
        app.run()
    

    Flask 过滤器

    字符串操作:

    {# 当变量未定义时,显示默认字符串,可以缩写为d #}
    <p>{{ name | default('No name', true) }}</p>
     
    {# 单词首字母大写 #}
    <p>{{ 'hello' | capitalize }}</p>
     
    {# 单词全小写 #}
    <p>{{ 'XML' | lower }}</p>
     
    {# 去除字符串前后的空白字符 #}
    <p>{{ '  hello  ' | trim }}</p>
     
    {# 字符串反转,返回"olleh" #}
    <p>{{ 'hello' | reverse }}</p>
     
    {# 格式化输出,返回"Number is 2" #}
    <p>{{ '%s is %d' | format("Number", 2) }}</p>
     
    {# 关闭HTML自动转义 #}
    <p>{{ '<em>name</em>' | safe }}</p>
     
    {% autoescape false %}
    {# HTML转义,即使autoescape关了也转义,可以缩写为e #}
    <p>{{ '<em>name</em>' | escape }}</p>
    {% endautoescape %}
    #用管道的形式,如果avatar(后端传过来的变量)的值不存在,则用default的值
    {{ avatar|default('xxx') }}    
    #这里的意思为获取avatar的长度,avatar为后端传过来的变量,可以是列表,也可以是字典
    {{ avatar|length }}
    

    数值操作:

    {# 四舍五入取整,返回13.0 #}
    <p>{{ 12.8888 | round }}</p>
    
    {# 向下截取到小数点后2位,返回12.88 #}
    <p>{{ 12.8888 | round(2, 'floor') }}</p>
    
    {# 绝对值,返回12 #}
    <p>{{ -12 | abs }}</p>
    

    列表操作:

    {# 取第一个元素 #}
    <p>{{ [1,2,3,4,5] | first }}</p>
     
    {# 取最后一个元素 #}
    <p>{{ [1,2,3,4,5] | last }}</p>
     
    {# 返回列表长度,可以写为count #}
    <p>{{ [1,2,3,4,5] | length }}</p>
     
    {# 列表求和 #}
    <p>{{ [1,2,3,4,5] | sum }}</p>
     
    {# 列表排序,默认为升序 #}
    <p>{{ [3,2,1,5,4] | sort }}</p>
     
    {# 合并为字符串,返回"1 | 2 | 3 | 4 | 5" #}
    <p>{{ [1,2,3,4,5] | join(' | ') }}</p>
     
    {# 列表中所有元素都全大写。这里可以用upper,lower,但capitalize无效 #}
    <p>{{ ['tom','bob','ada'] | upper }}</p>
    

    字典列表操作:

    {% set users=[{'name':'Tom','gender':'M','age':20},
                  {'name':'John','gender':'M','age':18},
                  {'name':'Mary','gender':'F','age':24},
                  {'name':'Bob','gender':'M','age':31},
                  {'name':'Lisa','gender':'F','age':19}]
    %}
     
     
     
    {# 按指定字段排序,这里设reverse为true使其按降序排 #}
    <ul>
    {% for user in users | sort(attribute='age', reverse=true) %}
         <li>{{ user.name }}, {{ user.age }}</li>
    {% endfor %}
    </ul>
     
    {# 列表分组,每组是一个子列表,组名就是分组项的值 #}
    <ul>
    {% for group in users|groupby('gender') %}
        <li>{{ group.grouper }}<ul>
        {% for user in group.list %}
            <li>{{ user.name }}</li>
        {% endfor %}</ul></li>
    {% endfor %}
    </ul>
     
    {# 取字典中的某一项组成列表,再将其连接起来 #}
    <p>{{ users | map(attribute='name') | join(', ') }}</p>
    

    内置过滤器: tojson配合js使用,注意这里要避免HTML自动转义,所以加上safe过滤器

    <script type="text/javascript">
    var users = {{ users | tojson | safe }};
    console.log(users[0].name);
    </script>
    

    自定义过滤器: 自定义过滤器其实就是一个函数,自己写即可

    def mylen(arg):#实现一个可以求长度的函数
        return len(arg)
    
    # 该函数实现给定一个区间返回区间的内容
    def interval(test_str, start, end):#过滤器中传递多个参数,第一个参数为被过滤的内容,第二第三个参数需要自己传入
        return test_str[int(start):int(end)]
    
    env = app.jinja_env
    env.filters['mylen'] = mylen      #注册自定义过滤器
    env.filters['interval'] = interval   #注册自定义过滤器
    
    @app.route("/") 
    def index(): 
      test_str = "hello" 
      return render_template("index.html", test_str=test_str)
    #--------------------------------------------------------------------
    jinja2模板
    <body>
        <h1>len: {{test_str|mylen}}</h1>
        <h1>interval: {{test_str|interval(0,2)}}</h1>    #test_str作为参数传到interval函数里
    </body>
    

    Flask 简单应用

    简单的参数传递: 通过配置不同的路由路径,接受不同的参数,最后返回给用户.

    from flask import Flask,render_template,request
    
    app = Flask(__name__)
    
    @app.route("/post/id=<id>")                       # 参数需要放在"<>"中,并且要与函数中传入的参数同名
    def post(id):                                     # 加入参数,函数名称要与上面的路由名称相同
        return "请求的参数是 %s" %id
    
    @app.route("/post/user=<name>&pass=<pasd>")       # 可同时传递多个参数,中间的&可有可无
    def user(name,pasd):
        return "用户名: %s 密码: %s" %(name,pasd)
    
    if __name__ == '__main__':
        app.run(host="0.0.0.0",port="80",debug=True)
    

    URL地址跳转 当输入正确用户名密码后,自动跳转到成功的页面上.

    from flask import Flask,render_template,request
    from flask import url_for,redirect
    
    app = Flask(__name__)
    @app.route("/")
    def index():
        return "<b> 这是首页,请先登录.. </b>"
    
    @app.route("/post/id=<username>")
    def Check(username):
        if username == "admim":
            return "用户%s登录完成了.." %username
        else:
            return redirect(url_for("login"))    #失败,跳转到登陆函数(界面)
    
    @app.route("/login/")
    def login():
        return "<b> 请登陆... </b>"
    
    if __name__ == '__main__':
        app.run(host="0.0.0.0",port="80",debug=True)
    

    ◆URL反向解析◆

    反转url主要用于模版和页面的重定向(从视图函数到url的转换)

    from flask import Flask,render_template,request
    from flask import url_for
    
    app = Flask(__name__)
    
    @app.route("/")
    def index():
        print(url_for("post",id="lyshark"))
        return "/"
    
    @app.route("/post/<id>")
    def post(id):
        return "<h1> hello %s </h1>" %id
    
    if __name__ == '__main__':
        app.run(host="0.0.0.0",port="80",debug=True)
    

    ◆简单的参数传递◆

    HTML index.html

    <body>
        <p>第一个flask页面</p>
        <p>姓名:{{ username }}</p>
        <p>height:{{ height }}</p>
    </body>
    

    后台 app.py

    from flask import Flask,url_for,redirect,render_template
    
    app = Flask(__name__)
    
    @app.route("/")
    def index():
        info = {
            "username":"lyshark",
            "gender":"man",
            "height":"165"
        }
    
        #如果有多个参数,可以将所有的参数放到字典中,然后以**kwargs的方式传递进去,info为上面定义的字典
        #这里直接写模版文件名称,如果在模版文件在temlate/html目录下,则这里需要写'html/index.html'
        return render_template("index.html",**info)  
    
        #渲染模版,传参数,如果参数较少,可以直接写关键字参数及值,如下:
      #return render_template('index.html',username='name',gender="man",height="178")
    
    if __name__ == '__main__':
        app.run(host="0.0.0.0",port="80",debug=True)
    

    ◆复杂的参数传递◆

    HTML index.html

    <body>
        <p>第一个flask页面</p>
        <p>姓名:{{ username }}</p>
        <p>height:{{ height }}</p>
        <hr>
        <p>{{ person.name }}---{{ person.age }}</p>  //此处对应上面py中定义的Person类
        <p>{{ city.bj }}</p>               //第一种取值方式
        <p>{{ city['tj'] }}</p>                       //第二种取值方式
    </body>
    

    后台 app.py

    from flask import Flask,url_for,redirect,render_template
     
    app = Flask(__name__)
     
    @app.route('/')
    def index():
        class Person(object):
            name='tttt'
            age=18
     
        p = Person()
        info = {
            'username' :'name',
            'gender':"man",
            'height' : "178",
            'person':p,
            'city':{
                'bj':"bj",
                'tj':'tj'
            }
     
        }
        return render_template('index.html',**info)
        #return render_template('index.html',username='name',gender="man",height="178")
     
    if __name__ == '__main__':
        app.run(debug=True)
    

    ◆自定义错误页◆

    @app.errorhandler(404)
    def page_noe_found(error):
        return render_template('home/404.html'),404
    
    @app.errorhandler(500)
    def page_noe_found(error):
        return render_template('home/500.html'),500
    

    ◆IF语句的使用◆

    HTML: index.html

    <body>
        {% if users and users.age >10 %}        #这里的users为py文件里传递的user字典,users.age为py文件user字典里的age
            <a href="#">{{ users.aa }}</a>
            <a href="#">{{  users.bbb}}</a>
        {% else %}
            <a href="#">登陆</a>
            <a href="#">注册</a>
        {% endif %}
    </body>
    

    后台: app.py

    from flask import Flask,url_for,redirect,render_template
    
    app = Flask(__name__)
    
    @app.route('/<is_login>')
    def index(is_login):
    
        if is_login == "1":        #模拟1为登陆成功
            user = {
                "aa":"test",
                'bbb':'注销',
                'age':"11"
            }
            return render_template('index.html',users=user)
        else:
            return render_template('index.html')
    
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    ◆FOR语句的使用◆

    HTML: index.html

    <body>
        {% for k,v in user.items() %}        #for语句
            <p>{{ k }}----{{ v }}</p>
        {% endfor %}
    </body>
    

    后台: app.py

    from flask import Flask,url_for,redirect,render_template
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        users = {
            'username':'tsdf',
            'age':11
        }
        return render_template('index.html',user=users)
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    ◆钩子函数的使用◆

    before_request函数,就是一个装饰器,他可以把需要设置为钩子函数的代码放到视图函数执行之前执行.

    from flask import Flask,url_for,redirect,render_template,request
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        print ('index')
        return 'index'
    
    @app.before_request
    def mybefore_request():
        print ('before_request')
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    Flask 常用开发片段

    实现记住密码功能: 在不使用框架的情况下,手撸登录验证功能.

    前端HTML页面

    <script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
    <script type="text/javascript">
      $(document).ready(function(){
            var strName = localStorage.getItem('keyName');
            var strPass = localStorage.getItem('keyPass');
            if(strName){
                $('#user').val(strName);
            }if(strPass){
                $('#pass').val(strPass);
            }
            if(strName!=null && strPass!=null)
                $('#remember').attr("checked",true);
        });
        function login_click(){
                var strName = $('#user').val();
                var strPass = $('#pass').val();
                if($('#remember').is(':checked')){
                    localStorage.setItem('keyName',strName);
                    localStorage.setItem('keyPass',strPass);
                }else{
                    localStorage.removeItem('keyName',strName);
                    localStorage.removeItem('keyPass');
                }
                window.location.reload();
            }
    </script>
    
    <body>
        <form action="/" method="post" onsubmit="return login_click();">
            账号: <input type="text" id="user" placeholder="用户名" name="username" /><br><br>
            密码: <input type="password" id="pass" placeholder="密码" name="password" /><br><br>
            记住密码: <input type="checkbox" id="remember">
            <input type="submit" value="用户登录"/>
        </form>
        <div>
            {% if flag == 1 %}
                <p>当前登录用户: {{ user }} 该用户密码是: {{ pasd }}</p>
            {% elif flag == 0 %}
                <p>登录失败了,你输入的密码有误.</p>
            {% endif %}
        </div>
    </body>
    

    后台代码

    from flask import Flask,render_template,request
    import re
    
    app = Flask(__name__)
    @app.route("/",methods=['GET','POST'])
    def index():
        if request.method == "GET":
            return render_template("index.html")
        elif request.method == "POST":
            username = request.form.get("username")
            password =request.form.get("password")
            if username != "" and password != "":                            # 用户名密码不能为空
                if re.findall(r"[a-zA-Z0-9]{4,15}$", username):              # 用户名不能含有特殊字符
                    if re.findall(r"[a-zA-Z0-9]{5,15}$", password):          # 密码必须符合安全要求
                        if username == "admin" and password == "admin123":
                            print("收到用户名: %s --->收到密码: %s" % (username, password))
                            return render_template("index.html", flag=1,user=username, pasd=password)
                        else:
                            return render_template("index.html", flag=0)
                    else:
                        return '''<script type="text/javascript">alert('错误,密码开头必须为字母!');</script>'''
                else:
                    return '''<script type="text/javascript">alert('错误,用户名存在特殊字符,或长度不符!');</script>'''
            else:
                return '''<script type="text/javascript">alert('您不能输入空的用户名或密码!');</script>'''
    
    if __name__ == '__main__':
        app.run()
    

    ◆实现用户登录功能◆

    style.css

    body {
        display: flex;
        align-items: center;
        justify-content: center;
        text-align: -webkit-center;
        line-height: 0.5;
        background: aliceblue;
    }
    .form-bg{
        background: #00b4ef;
    }
    .form-horizontal{
        background: #fff;
        padding-bottom: 10px;
        border-radius: 15px;
        text-align: center;
    }
    .form-horizontal .heading{
        display: block;
        font-size: 35px;
        font-weight: 700;
        padding: 35px 0;
        border-bottom: 1px solid #f0f0f0;
        margin-bottom: 30px;
    }
    .form-horizontal .form-group{
        padding: 0 40px;
        margin: 0 0 25px 0;
        position: relative;
    }
    .form-horizontal .form-control{
        background: #f0f0f0;
        border: none;
        border-radius: 20px;
        box-shadow: none;
        padding: 0 20px 0 45px;
        height: 40px;
        transition: all 0.3s ease 0s;
    }
    .form-horizontal .form-control:focus{
        background: #e0e0e0;
        box-shadow: none;
        outline: 0 none;
    }
    .form-horizontal .form-group i{
        position: absolute;
        top: 12px;
        left: 60px;
        font-size: 17px;
        color: #c8c8c8;
        transition : all 0.5s ease 0s;
    }
    .form-horizontal .form-control:focus + i{
        color: #00b4ef;
    }
    .form-horizontal .fa-question-circle{
        display: inline-block;
        position: absolute;
        top: 12px;
        right: 60px;
        font-size: 20px;
        color: #808080;
        transition: all 0.5s ease 0s;
    }
    .form-horizontal .fa-question-circle:hover{
        color: #000;
    }
    .form-horizontal .text{
        float: left;
        margin-left: 7px;
        line-height: 20px;
        padding-top: 5px;
        text-transform: capitalize;
    }
    .form-horizontal .btn{
        font-size: 14px;
        color: #fff;
        border-radius: 100px;
        padding: 10px 70px;
        border: none;
        text-transform: capitalize;
        transition: all 0.5s ease 0s;
    }
    @media only screen and (max- 479px){
        .form-horizontal .form-group{
            padding: 0 25px;
        }
        .form-horizontal .form-group i{
            left: 45px;
        }
        .form-horizontal .btn{
            padding: 10px 20px;
        }
    }
    

    login.html

    <head>
    <link rel='stylesheet' href='https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'>
    <link href="http://cdn.bootcss.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="static/style.css" />
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-offset-3 col-md-6">
                <form action="/login" method="post" class="form-horizontal">
                    <span class="heading">用 户 登 录</span>
                    <div class="form-group">
                        {{ form.username }}
                        <i class="fa fa-user"></i>
                    </div>
                    <div class="form-group help">
                        {{ form.password }}
                        <i class="fa fa-lock"></i>
                        <a href="#" class="fa fa-question-circle"></a>
                    </div>
                    <div class="form-group">
                        <button type="submit" class="btn btn-success">登 录 后 台</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
    </body>
    

    flask.py

    from flask import Flask, render_template, request, redirect
    from wtforms import Form,validators,widgets
    from wtforms.fields import simple,html5
    import sqlite3
    app = Flask(__name__, template_folder="templates")
    
    class LoginForm(Form):
        username = simple.StringField(
            validators=[
                validators.DataRequired(message=''),
                validators.Length(min=4, max=15, message=''),
                validators.Regexp(regex="[0-9a-zA-Z]{4,15}", message='')
            ],
            widget=widgets.TextInput(),
            render_kw={"class":"form-control",
                       "placeholder":"请输入用户名或电子邮件"}
        )
        password = simple.PasswordField(
            validators=[
                validators.DataRequired(message=''),
                validators.Length(min=5, max=15,message=''),
                validators.Regexp(regex="[0-9a-zA-Z]{5,15}",message='')
            ],
            widget=widgets.PasswordInput(),
            render_kw={"class":"form-control",
                       "placeholder":"请输入密码"}
        )
    
    def select(temp):
        try:
            conn = sqlite3.connect("D://data.db")
            cursor = conn.cursor()
            row = cursor.execute('select id from user where username="{}" and password="{}"'
                                 .format(temp['username'], temp['password']))
            if len(row.fetchall()) != 0:
                return 1
            else:
                return 0
        except Exception:
            return 0
    
    @app.route("/login",methods=['GET','POST'])
    def Login():
        if request.method == 'GET':
            RetForm = LoginForm()
            return render_template('login.html', form=RetForm)
        else:
            RetForm = LoginForm(formdata=request.form)
            if RetForm.validate():
                temp = RetForm.data
                ret = select(temp)
                if ret != 1:
                    return '''<script type="text/javascript">alert('用户名或密码输入有误!');</script>'''
                else:
                    return '''<script type="text/javascript">alert('登录完成!');</script>'''
            return render_template('login.html', form=RetForm)
    
    if __name__ == '__main__':
        app.run()
    

    ◆实现用户注册功能◆

    register.html

    <head>
    <link rel='stylesheet' href='https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'>
    <link href="http://cdn.bootcss.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="static/style.css" />
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-offset-3 col-md-6">
                <form action="/register" method="post" class="form-horizontal">
                    <span class="heading">用 户 注 册</span>
                    <div class="form-group">
                        {{ form.username }}
                        <i class="fa fa-user"></i>
                        <a href="/login" class="fa fa-question-circle"></a>
                    </div>
                    <div class="form-group">
                        {{ form.email }}
                        <i class="fa fa-envelope"></i>
                    </div>
                    <div class="form-group">
                        {{ form.password }}
                        <i class="fa fa-lock"></i>
                    </div>
                    <div class="form-group">
                        {{ form.RepeatPassword }}
                        <i class="fa fa-unlock-alt"></i>
                    </div>
                    {{ form.submit }}
                </form>
            </div>
        </div>
    </div>
    </body>
    

    app.py

    from flask import Flask, render_template, request, redirect
    from wtforms import Form,validators,widgets
    from wtforms.fields import simple,html5
    
    app = Flask(__name__, template_folder="templates")
    class RegisterForm(Form):
        username = simple.StringField(
            #label='注册用户:',
            validators=[
                validators.DataRequired(message='用户名不能为空'),
                validators.Length(min=6, max=18, message='用户名长度必须大于%(min)d且小于%(max)d')
            ],
            widget=widgets.TextInput(),
            render_kw={'class': 'form-control',
                       "placeholder":"输入注册用户名"}
        )
        email = simple.StringField(
            #label='用户邮箱:',
            validators=[validators.DataRequired(message='邮箱不能为空'),validators.Email(message="邮箱格式输入有误")],
            render_kw={'class':'form-control',
                       "placeholder":"输入Email邮箱"}
        )
        password = simple.PasswordField(
            #label='用户密码:',
            validators=[
                validators.DataRequired(message='密码不能为空'),
                validators.Length(min=5, message='用户名长度必须大于%(min)d'),
                validators.Regexp(regex="[0-9a-zA-Z]{5,}",message='密码不允许使用特殊字符')
            ],
            widget=widgets.PasswordInput(),
            render_kw={'class': 'form-control',
                       "placeholder":"输入用户密码"}
        )
        RepeatPassword = simple.PasswordField(
            #label='重复密码:',
            validators=[
                validators.DataRequired(message='密码不能为空'),
                validators.Length(min=5, message='密码长度必须大于%(min)d'),
                validators.Regexp(regex="[0-9a-zA-Z]{5,}",message='密码不允许使用特殊字符'),
                validators.EqualTo("password",message="两次密码输入必须一致,龟孙")
            ],
            widget=widgets.PasswordInput(),
            render_kw={'class': 'form-control',
                       "placeholder":"再次输入密码"}
        )
        submit = simple.SubmitField(
            label="用 户 注 册",
            render_kw={ "class":"btn btn-success" }
        )
    
    @app.route('/register', methods=['GET', 'POST'])
    def Register():
        if request.method == 'GET':
            RetForm = RegisterForm()
            return render_template('register.html', form=RetForm)
        else:
            RetForm = RegisterForm(formdata=request.form)
            if RetForm.validate():
                print('接收到数据:', RetForm.data)
                return '''<script>alert('您的注册请求已提交!');</script>'''
            else:
                print(RetForm.errors)
            return render_template('register.html', form=RetForm)
    
    if __name__ == '__main__':
        app.run()
    

    选择框使用技巧: 单选框,复选框,多选框等.

    前端代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
        <title>页面选择</title>
    
    </head>
    <body>
    <form method="post">
        <p>{{ form.gender.label }} {{form.gender}} {{form.gender.errors[0] }}</p>
        <p>{{ form.city.label }} {{form.city}} {{form.city.errors[0] }} </p>
        <p>{{ form.hobby.label }} {{form.hobby}} {{form.hobby.errors[0] }}</p>
        <p>{{ form.favor.label }} {{form.favor}} {{form.favor.errors[0] }}</p>
        <input type="submit" value="提交表格">
    </form>
    </body>
    </html>
    

    后台代码

    from flask import Flask, render_template, request, redirect
    from wtforms import Form,validators,widgets
    from wtforms.fields import simple,html5,core
    
    app = Flask(__name__,template_folder="templates")
    
    class RegisterForm(Form):
        gender = core.RadioField(
            label="性别:",choices=((0,"男"),(1,"女"),(0,"两面派")),coerce=int  #限制是int类型的
        )
        city = core.SelectField(
            label="选择城市:",
            choices=(
                ("shandong","山东省"),("shanghai","上海市"),
                ("beijingshi","北京市"),("neimenggu","内蒙古")
            ),
            render_kw={'class': 'btn btn-primary dropdown-toggle'}
        )
        hobby = core.SelectMultipleField(
            label='爱好:',
            choices=((1, '唱'),(2, '跳'),(3,'rap'),(4,'篮球')),
            coerce=int,
            render_kw = {'class': 'form-control'}
        )
        favor = core.SelectMultipleField(
            label="特长:",
            choices=((1, 'Python把妹'),(2, '渗透把妹'),(3,"运维把妹"),(4,"科学把妹")),
            widget = widgets.ListWidget(prefix_label=False),
            option_widget = widgets.CheckboxInput(),
            coerce = int, default = [1, 2 , 4],
        )
    
    @app.route('/submit',methods=["GET","POST"])
    def submit():
        if request.method=="GET":
            form = RegisterForm(data={'gender': 1}) # 指定性别的默认值是1
            return render_template("submit.html",form=form)
        else:
            form = RegisterForm(formdata=request.form)
            if form.validate():
                print('提交的值为:', form.data)
                return '''<script type="text/javascript">alert('您的请求已提交!');</script>'''
            else:
                print("提交数据错误..")
            return render_template('submit.html', form=form)
    
    if __name__ == '__main__':
        app.run()
    

    ◆实现文件上传◆

    HTML: upload.html

    <script type="text/javascript">
        function CheckFileType(filename)
        {
            var flag = false;
            var arry = ["bmp","jpg"];
            var index = filename.lastIndexOf(".");
            var ext = filename.substr(index+1);
            for(var i=0;i<arry.length;i++)
            {
                if(ext == arry[i])
                {
                    flag=true;
                    break;
                }
            }
            if(!flag){alert('错误,文件名后缀不合法!');}
        }
    </script>
    
    <body>
        <form action="/upload" enctype="multipart/form-data" method="post">
            <input type="file" name="file" onchange="CheckFileType(this.value)">
            <input type="submit" value="上传文件">
        </form>
        <p style="color: green">状态: {{ file_flage }}</p>
    </body>
    

    后台: app.py

    from flask import Flask,render_template,request
    import os,uuid
    
    app = Flask(__name__)
    app.config['MAX_CONTENT_LENGTH'] = 3000000   # 限制文件上传最大为3MB
    
    @app.route("/upload",methods=['GET','POST'])
    def upload_file():
        if request.method == "GET":
            return render_template("upload.html")
        elif request.method == "POST":
            file = request.files["file"]
            filename = str(file.filename)
            if len(filename) >= 20:          # 限制文件名的长度必须在20个字符以内
                return render_template("upload.html",file_flage="文件名长度超出了限制!")
            else:
                if filename.find(".") >= 0:  # 查找文件中是否包含点这个字符
                    filetype = file.filename.split(".")[1]     # 取出文件类型,后期做判断
                    if filetype != None and filetype == "bmp": # 后缀格式必须是bmp结尾
                        uid = uuid.uuid4()                     # 生成随机名称
                        save_file_name = str(uid) + "." + filetype  # 拼接名称
                        file.save(save_file_name)                   # 保存文件
                        return render_template("upload.html",file_flage="文件上传成功 {}".format(save_file_name))
                else:
                    return render_template("upload.html",file_flage="没有选择文件,或不是图片格式,上传失败!")
        return render_template("upload.html",file_flage="文件上传失败,未知错误!")
    
    if __name__ == '__main__':
        app.run()
    

    实现文件下载

    <script type="text/javascript">
        function Download(filename)
        {
            if(filename){window.location.href='/download/?path=' + filename}
        }
    </script>
    <body>
        <form action="/download" enctype="multipart/form-data" method="get">
            <input type="text" name="down" onchange="Download(this.value)"/>
            <input type="submit" value="下载文件" >
        </form>
    </body>
    
    from flask import Flask, render_template, request, Response
    app = Flask(__name__)
    
    @app.route('/download/', methods=['GET', 'POST'])
    def download_file():
        if request.method == 'GET':
            args = request.args.get("path").replace("/","").replace("\","")
            args = args.replace("<>","").replace("<!--","")
            args = "./templates/" + args
            print("下载的文件: {}".format(args))
            def send_file():
                store_path = args
                with open(store_path, 'rb') as targetfile:
                    while 1:
                        data = targetfile.read(10 * 1024 * 1024)   # 每次读取10M
                        if not data:
                            break
                        yield data
            response = Response(send_file(), content_type='application/octet-stream')
            response.headers["Content-disposition"] = 'attachment; filename=%s'%args.split("/")[2]  # 取出下载的名字
            return response
    
    if __name__ == '__main__':
        app.run()
    

    实现前端组合数据,后端接受

    <body>
        <script src="https://code.jquery.com/jquery-3.4.1.min.js" type="text/javascript"></script>
        <script type="text/javascript">
            function SendAjax(){
                var username = $('input[name="username"]').val();
                var password = $('input[name="password"]').val();
                var json = {"username":username,"password":password};
                $.ajax({
                    url:"/dataFromAjax",
                    contentType: "POST",
                    data:json,
                    success:function(data){
                        if(data=="1"){alert("请求已经提交.");}
                    },
                    error:function(){
                         //alert("执行失败了...")
                    }
                });
            }
        </script>
    
        <form action="/dataFromAjax" method="post">
            用户账号: <input type="text" placeholder="用户账号" name="username" /><br><br>
            用户密码: <input type="text" placeholder="用户密码" name="password" /><br><br>
            <input type="button" value="发送数据" onclick="SendAjax()">
        </form>
    </body>
    
    from flask import Flask,render_template,request
    from flask import jsonify
    
    app = Flask(__name__)
    
    @app.route("/")
    def index():
        return render_template("index.html")
    
    @app.route("/dataFromAjax",methods=['GET'])
    def recv():
        username = request.args.get("username")
        password = request.args.get("password")
        if(username=="" or password ==""):
            return "0"
        else:
            print("收到客户{} 密码 {} ".format(username,password))
            return "1"
    
    if __name__ == '__main__':
        app.run()
    

    ◆实现Session◆

    from flask import Flask,render_template,request
    from flask import session,url_for,escape,redirect
    import os
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():                               #自动验证session
        if 'username' in session:
            return '用户 %s 已经登陆成功...' % escape(session['username'])
        return '您还没有登陆呢...'
    
    
    @app.route('/login', methods=['GET', 'POST'])
    def login():                                 #登陆session
        if request.method == 'POST':
            session['username'] = request.form['username']
            return redirect(url_for('index'))
        return '''
            <form action="" method="post">
                <p><input type=text name=username>
                <p><input type=submit value=登陆>
            </form>
        '''
    @app.route('/get')
    def get():                                   #获取session
        return "用户: %s" %session.get('username')
    
    @app.route('/logout')
    def logout():                                #注销session
        session.pop('username', None)
        # session.clear()                #清空session里的所有数据
        return redirect(url_for('index'))
    
    app.secret_key = os.urandom(24)             #加盐,服务端每次重启都会变化
    if __name__ == '__main__':
        app.run()
    

    ◆表格结构遍历◆

    HTML index.html

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
    <body>
        <form action="/" method="post">
            <input type="text" placeholder="姓名" name="username" />
            <input type="text" placeholder="性别" name="usersex" />
            <input type="text" placeholder="邮箱" name="email" />
            <input type="text" placeholder="手机号" name="phone" />
            <input type="text" placeholder="留言内容" name="usertext" />
            <input type="submit" value="点我提交表单"/>
        </form>
        <br>
         <table border="1" class="table table-hover">
                <thead>
                <th>用户IP</th> <th>用户姓名</th> <th>性别</th> <th>邮箱</th> <th>手机号</th><th>留言</th>
                </thead>
                <tbody>
                    {% for temp in user %}
                        <tr>
                            <td>{{ temp.userip }}</td>
                            <td>{{ temp.username }}</td>
                            <td>{{ temp.usersex }}</td>
                            <td>{{ temp.email }}</td>
                            <td>{{ temp.phone }}</td>
                            <td>{{ temp.usertext }}</td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
    </body>
    

    后台: app.py

    from flask import Flask,render_template,request
    import json
    
    app = Flask(__name__)
    temp = [ ]
    
    @app.route("/",methods=['GET','POST'])
    def index():
        if request.method == "GET":
            return render_template("index.html", user=temp)
        elif request.method == "POST":
            userip = str(request.remote_addr)
            username = request.form.get("username")
            usersex = request.form.get("usersex")
            email = request.form.get("email")
            phone = request.form.get("phone")
            usertext = request.form.get("usertext")
            if username != "" and usertext != "" and usersex != "" and email != "":
                data = {"userip":userip,"username":username,"usersex":usersex,"email":email,"phone":phone,"usertext":usertext}
                temp.append(data)                       #追加数据到列表
                with open("data.json", "w", encoding="UTF-8") as f:
                    s = json.dump(temp, f, ensure_ascii=False)
                return render_template("index.html",user=temp)
            return  render_template("index.html",user=temp)
    
    if __name__ == '__main__':
        app.run()
    

    模态对话框的使用: 后台接收参数,与上方相同,区别在于使用BootCSS弹框.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>弹出式编辑框</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
        <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
    </head>
    <body>
    <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@mdo">编辑主机</button>
        <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
          <div class="modal-dialog" role="document">
            <div class="modal-content">
              <div class="modal-header">
                <h5 class="modal-title" id="exampleModalLabel">编辑运维主机</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">X</span>
                </button>
              </div>
    
              <!--主体框架,使用form表单提交-->
              <div class="modal-body" >
                <form action="/edit" method="post">
                  <!--按钮主体框架-->
                  <div class="form-group">
                    <label class="form-inline" for="recipient-name" class="col-form-label">主机名称:</label>
                    <input type="text" class="form-control" id="recipient-name" name="hostname">
                  </div>
                  <div class="form-group">
                    <label class="form-inline" for="recipient-name" class="col-form-label">IP地址:</label>
                    <input type="text" class="form-control" id="recipient-name" name="ipaddress">
                  </div>
                    <!--关闭事件,此处只有两个按钮-->
                  <div style="display: block;text-align: center;" class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭窗口</button>
                    <button type="submit" class="btn btn-primary">提交数据</button>
                  </div>
               </form>
            </div>
          </div>
        </div>
    </div>
    </body>
    </html>
    
  • 相关阅读:
    test
    Android初学-AsyncTask下载网络图片
    SFTP Using Chilkat Active component
    test wilddog
    c# multi-ply download ui
    VB6 Common Dialog
    Advanced Find and Replace(文件内容搜索替换工具)v7.8.1简体中文破解版
    【Unity Shaders】Shader中的光照
    GDAL不支持创建PCIDSK的面状矢量格式
    CentOs查看文件的几种方式
  • 原文地址:https://www.cnblogs.com/LyShark/p/11136289.html
Copyright © 2020-2023  润新知