• 【Python百日进阶-WEB开发-冲進Flask】Day181 - Flask简单流程


    一、day01项目环境和结构搭建

    1.1 新建虚拟环境

    E:\VirtualEnv\cmd
    virtualenv RushInFlask
    cd rushinflask
    scripts\activate
    pip list
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    1.2 安装Flask

    pip install -i https://mirrors.aliyun.com/pypi/simple flask
    pip list
    
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    1.3 配置Python解释器

    在这里插入图片描述

    二、后端知识要点

    2.1 Flask 文档

    https://dormousehole.readthedocs.io/en/latest/
    在这里插入图片描述

    2.2 实例化flask对象

    2.2.1 新建独立的配置文件settings.py

    在这里插入图片描述

    2.2.2 实例化flask对象时加载配置文件

    import settings
    app = Flask(__name__)
    app.config.from_object(settings)
    
    • 1
    • 2
    • 3

    2.3 基本路由

    2.3.1 常用路由及唯一性

    ######### 常用路由,建议路由格式为 '/path',即前有后无,这样可以确保路由的唯一性
    @app.route('/')  # 路由  http://127.0.0.1:5000/
    def hello_world():  # 视图
        return 'Hello World~~~!!!'
    
    • 1
    • 2
    • 3
    • 4

    2.3.2 路由底层调用

    ########## 路由底层调用
    def index():
        return '通过add_url_rul返回!'
    app.add_url_rule('/index/', view_func=index)
    
    • 1
    • 2
    • 3
    • 4

    2.4 路由规则

    2.4.1 字符串路由

    data = {'bj': '北京', 'sh': '上海', 'gz': '广州', 'sz': '深圳'}
    @app.route('/getcity//')  # city是变量名,默认字符串
    def get_city(city):
        print(type(city))
        return f'进入{data.get(city)}市'
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.4.2 path路径路由

    @app.route('/index/')  # http://127.0.0.1:5001/index/username/page_1
    def get_path(p):
        print(type(p))  # str
        return p  # 页面返回 username/page_1
    
    • 1
    • 2
    • 3
    • 4

    2.4.3 数字(整数int、浮点数float)路由

    @app.route('/add/')  # 变量类型不是字符串需要指定,可以是int,float,path,uuid
    def add(num):
        result = 10 + num
        return f'10+{num}={result}'
    
    • 1
    • 2
    • 3
    • 4

    2.4.4 多参数路由

    # 路由多参数传递
    @app.route('/add//')  # 变量类型不是字符串需要指定,可以是int,float,path,uuid
    def add1(num1, num2):
        result = num1 + num2
        return f'{num1}+{num2}={result}'
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.4.5 UUID路由

    import uuid
    res_uid = uuid.uuid4()
    print(res_uid)  # af8e20c0-876b-4ab2-83d1-f0851e46ac49
    # 指定了UUID类型,后面必须放符合uuid格式的变量,接收到的也是uuid变量
    @app.route('/index/')  # http://127.0.0.1:5001/index/af8e20c0-876b-4ab2-83d1-f0851e46ac49
    def get_uuid(uid):
        print(type(uid))  # 
        return str(uid)  # af8e20c0-876b-4ab2-83d1-f0851e46ac49
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.5 返回值:Response对象

    2.5.1 返回值-字符串

    @app.route('/')  # 路由  http://127.0.0.1:5000/
    def hello_world():  # 视图
        return 'Hello World~~~!!!'
    
    • 1
    • 2
    • 3

    2.5.2 返回值-元组:需要转换为Response对象

    from flask import Response
    tuple1 = ('12', 'ab', '32')
    @app.route('/index1')
    def index1():
        return Response(tuple1)  # 页面显示 12ab32
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.5.3 返回值-Response对象

    2.5.4 返回值-渲染模板render_template

    ########### app与模板的结合,默认使用Jinjia2模板引擎,模板文件夹默认为templates
    from flask import render_template
    @app.route('/', endpoint='index')   # endpoint为路由别名
    def index():
        return render_template('index.html')     # Jinjia2模板引擎转化为字符串格式
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.5.5 返回值-重定向redirect

    # 接收页面数据
    from flask import redirect
    @app.route('/register', methods=['GET', 'POST'])
    def register():
        if request.method == 'POST':
            # 提取 post 方式提交的数据
            username1 = request.form.get('username')
            password1 = request.form.get('password')
            print(username1, password1)
            users.append(request.form.to_dict())
            return redirect('index.html') 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.6 request对象

    ########### request 对象
    from flask import request 
    @app.route('/index2')
    def index2():
        print(request.headers)
        print(request.path)
        print(request.base_url)
        print(request.url)
        print(request.full_path)
        return 'request对象'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.7 url_for反向解析

    2.7.1 endpoint为路由指定别名

    别名可以与函数名不一致

    ########### app与模板的结合,默认使用Jinjia2模板引擎,模板文件夹默认为templates
    @app.route('/', endpoint='index')   # endpoint为路由别名
    def index():
        return render_template('index.html')     # Jinjia2模板引擎转化为字符串格式
    
    • 1
    • 2
    • 3
    • 4

    2.7.2 url_for反向解析

    users = []
    # 接收页面数据
    @app.route('/register', methods=['GET', 'POST'])
    def register():
        if request.method == 'POST':
            # 提取 post 方式提交的数据
            username1 = request.form.get('username')
            password1 = request.form.get('password')
            print(username1, password1)
            users.append(request.form.to_dict())
            return redirect(url_for('index'))    # 路由endpoint别名反向解析,然后重定向会有两次响应
        if request.method == 'GET':
            # 提取 get 方式提交的数据
            print(request.args)
            return render_template('register.html')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.8 渲染模板时向前端传递参数

    2.8.1 字典列表转化为json字符串

    json.dumps(users)
    
    • 1

    2.8.2 渲染模板时向前端传递参数

    @app.route('/show')
    def show():
        context = {}
        context['user'] = json.dumps(users)
        msg = '

    我不想被转义

    '
    return render_template('show.html', context=users, msg=msg)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.9 打印当前项目路由映射表

    print(app.url_map)      # 路由表
    
    • 1

    三、前端知识要点

    3.1 表单提交路由、模式和变量名

    1. 表单提交路由:/register
    2. 表单提交模式:post
    3. 表单提交变量名:name=“username”
    <div>
    	
    	<form action="register" method='post'>
    		<p><input type="text" name="username" placeholder="请输入用户名">p>
    		<p><input type="password" name="password" placeholder="请输入密码">p>
    		<p><input type="submit" value="注册">p>
    	form>
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.2 接收后端传来的变量 {{ msg }}

    3.3 循环结构

    • loop.index 取序号
    • loop.last 判断是否是最后一个,返回布尔值
    {% for item in context %}
    	<tr {% if loop.last %} style="background-color: deeppink;" {% endif %}>
    		<td>{{loop.index}}td>
    		<td>{{item.username}}td>
    		<td>{{item.password}}td>
    	tr>
    {% endfor %}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.4 判断结构

    {% if loop.last %} style="background-color: deeppink;" 
    {% else %}
    {% endif %}>
    
    • 1
    • 2
    • 3

    3.5 过滤器

    3.5.1 列表过滤器

    <p>列表过滤器p>
    {{ context|length }}<br>
    {{ context|first }}<br>
    {{ context|last }}<br>
    {{ [1,2,3,4]|sum }}<br>
    {{ [2,6,5,10,8]|sort }}<br>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.5.2 字典过滤器

    <p>字典过滤器p>
    items()取字典的所有key和value
    <br>
    {% for k,v in context.0.items() %}
    	{{k}}--{{v}}
    {% endfor %}
    <br>
    keys()取字典的所有key
    <br>
    {% for k in context.0.keys() %}
    	{{k}}
    {% endfor %}
    <br>
    values()取字典的所有value
    <br>
    {% for v in context.0.values() %}
    	{{v}}
    {% endfor %}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    四、项目完整代码

    4.1 项目目录结构

    在这里插入图片描述

    4.2 后端代码

    4.2.1 settings.py文件

    # 配置文件
    
    ENV = 'development'
    DEBUG = True
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.2.2 app.py

    # Flask 文档  https://dormousehole.readthedocs.io/en/latest/
    from flask import Flask, Response, request, render_template, redirect, url_for
    import settings
    import json
    
    app = Flask(__name__)
    app.config.from_object(settings)
    
    
    ######### 常用路由,建议路由格式为 '/path',即前有后无,这样可以确保路由的唯一性
    # @app.route('/')  # 路由  http://127.0.0.1:5000/
    # def hello_world():  # 视图
    #     return 'Hello World~~~!!!'
    
    
    # ########## 路由底层调用
    # def index():
    #     return '通过add_url_rul返回!'
    # app.add_url_rule('/index/', view_func=index)
    
    
    ######### 路由变量规则
    data = {'bj': '北京', 'sh': '上海', 'gz': '广州', 'sz': '深圳'}
    @app.route('/getcity//')  # city是变量名,默认字符串
    def get_city(city):
        print(type(city))
        return f'进入{data.get(city)}市'
    
    
    @app.route('/add/')  # 变量类型不是字符串需要指定,可以是int,float,path,uuid
    def add(num):
        result = 10 + num
        return f'10+{num}={result}'
    
    # 路由多参数传递
    @app.route('/add//')  # 变量类型不是字符串需要指定,可以是int,float,path,uuid
    def add1(num1, num2):
        result = num1 + num2
        return f'{num1}+{num2}={result}'
    
    
    @app.route('/index/')  # http://127.0.0.1:5001/index/username/page_1
    def get_path(p):
        print(type(p))  # str
        return p  # 页面返回 username/page_1
    
    
    import uuid
    res_uid = uuid.uuid4()
    # print(res_uid)  # af8e20c0-876b-4ab2-83d1-f0851e46ac49
    # 指定了UUID类型,后面必须放符合uuid格式的变量,接收到的也是uuid变量
    @app.route('/index/')  # http://127.0.0.1:5001/index/af8e20c0-876b-4ab2-83d1-f0851e46ac49
    def get_uuid(uid):
        print(type(uid))  # 
        return str(uid)  # af8e20c0-876b-4ab2-83d1-f0851e46ac49
    
    
    ########### Response 对象
    tuple1 = ('12', 'ab', '32')
    @app.route('/index1')
    def index1():
        return Response(tuple1)  # 页面显示 12ab32
    
    
    ########### request 对象
    @app.route('/index2')
    def index2():
        print(request.headers)
        print(request.path)
        print(request.base_url)
        print(request.url)
        print(request.full_path)
        return 'request对象'
    
    
    ########### app与模板的结合,默认使用Jinjia2模板引擎,模板文件夹默认为templates
    @app.route('/', endpoint='index')   # endpoint为路由别名
    def index():
        return render_template('index.html')     # Jinjia2模板引擎转化为字符串格式
    
    
    users = []
    # 接收页面数据
    @app.route('/register', methods=['GET', 'POST'])
    def register():
        if request.method == 'POST':
            # 提取 post 方式提交的数据
            username1 = request.form.get('username')
            password1 = request.form.get('password')
            print(username1, password1)
            users.append(request.form.to_dict())
            return redirect(url_for('index'))    # 路由endpoint别名反向解析,然后重定向会有两次响应
        if request.method == 'GET':
            # 提取 get 方式提交的数据
            print(request.args)
            return render_template('register.html')
    
    
    @app.route('/show')
    def show():
        context = {}
        context['user'] = json.dumps(users)
        msg = '

    我不想被转义

    '
    return render_template('show.html', context=users, msg=msg) if __name__ == '__main__': print(app.url_map) # 路由表 app.run(port=5001)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111

    4.3 前端代码

    4.3.1 index.html

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title>首页title>
    	head>
    	<body>
    		<a href="/register">注册<br>a>
    		<a href="">登录<br>a>
    		<a href="/show">展示用户<br>a>
    	body>
    html>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    4.3.2 register.html

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title>用户注册title>
    		<style type="text/css">
    			div{
    				width: 50%;
    				height: 180px;
    				border: 2px solid brown;
    			}
    		style>
    	head>
    	<body>
    		<h1>欢迎注册h1>
    		<div>
    			
    			<form action="register" method='post'>
    				<p><input type="text" name="username" placeholder="请输入用户名">p>
    				<p><input type="password" name="password" placeholder="请输入密码">p>
    				<p><input type="submit" value="注册">p>
    			form>
    		div>
    
    	body>
    html>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在这里插入图片描述

    4.3.3 show.html

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title>用户展示title>
    	head>
    	<body>
    		<h1>用户展示h1>
    		<ul>
    			{% for item in context %}
    				<li> {{item.username}}  {{item.password}} li>
    			{% endfor %}
    		ul>
    		<table border="1" cellspacing="0" cellpadding="0">
    			<tr>
    				<th>序号th>
    				<th>用户名th>
    				<th>密码th>
    			tr>
    			{% for item in context %}
    				<tr {% if loop.last %} style="background-color: deeppink;" {% endif %}>
    					<td>{{loop.index}}td>
    					<td>{{item.username}}td>
    					<td>{{item.password}}td>
    				tr>
    			{% endfor %}
    		table>
    		<hr >
    		<p>共有{{context|length}}人p>
    		<p>{{ msg|safe }}p>
    		<p>{{ '%s is %d years old' | format('lily', 18) }}p>
    		<hr >
    		<p>列表过滤器p>
    		{{ context|length }}<br>
    		{{ context|first }}<br>
    		{{ context|last }}<br>
    		{{ [1,2,3,4]|sum }}<br>
    		{{ [2,6,5,10,8]|sort }}<br>
    		<hr >
    		<p>字典过滤器p>
    		items()取字典的所有key和value
    		<br>
    		{% for k,v in context.0.items() %}
    			{{k}}--{{v}}
    		{% endfor %}
    		<br>
    		keys()取字典的所有key
    		<br>
    		{% for k in context.0.keys() %}
    			{{k}}
    		{% endfor %}
    		<br>
    		values()取字典的所有value
    		<br>
    		{% for v in context.0.values() %}
    			{{v}}
    		{% endfor %}
    
    
    	body>
    html>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    在这里插入图片描述

  • 相关阅读:
    java实现hbase数据导出
    【软件】Ubuntu16.04升级git最新版,升级python到3.7.
    2. Object中equals和toStirng 源码分析
    Google MLOps白皮书:MLOps实践者指南Part I MLOps生命周期及核心能力
    凌特杯,第二届,数字音频传输。simulink matlab
    不知道图片加文字水印怎么弄?这3个方法自媒体达人必学
    API 接口:原理、设计与应用
    【IPC 通信】信号处理接口 Signal API(2)
    基于PHP+MYSQL高等数学在线学习教学系统的设计与实现
    在IDEA中使用Git
  • 原文地址:https://blog.csdn.net/yuetaope/article/details/122872934