• Python Web 之 Flask


    FLASK

    一、概述

    flask是一个基于python并依赖于Jinja2模板引擎和WerkZeug WSGI(Web Server Gatewey InterFace.web)服务的框架

    WSGI:服务网关接口,提供处理网络请求相关的功能

    hello world

    from flask import Flask
    
    # 创建flask的程序实例
    app = Flask(__name__)
    
    @app.route('/') # 路由配置
    
    # 视图函数
    def index():
        return "<h1>欢迎访问</h1>"
    
    # 启动服务
    if __name__ == "__main__":
        app.run(debug=True)
    

    二、 定义路由

    路由是为了匹配用户的请求地址,会自动执行视图函数。视图函数中必须有返回值,返回字符串显示到响应的页面中。

    2. 无参数

    定义路由

    @app.route('/地址')

    定义视图函数

    def funcName():
        return "" # 响应到页面的内容
    

    例如:

    @app.route("/") # '/'表示根路径
    def index(): #匹配到路径后执行的视图函数
        return "首页"
    

    3. 带参数

    变量:<变量名>

    @app.route("/login/<name>")
    def login(name):
        return "欢迎%s登陆"%name
    

    如需要设置默认路由,则在视图函数中传参直接设置def login(name="Chancey")

    还有一种方式,就是在路由装饰器中传入一个字典@app.route("/login/<name>",defaults={"name":"游客"})

    4. 类型转换器

    缺省:字符串,不能包含'/'

    int:转换整数 float:转换小数 path:字符串,运行包含'/'

    使用:@app.route('/show/<int:num>')在路径中直接转换

    例如

    配置路由:/calaute/<number1>/<number2>,视图函数中接收参数,返回类似于“3 + 5 = 8”

    @app.route('/calaute/<num1>/<num2>')
    def calaute(num1,num2):
        return "%s + %s = %d"%(num1,num2,int(num1)+int(num2))
    

    注意:路径中的参数变量永远是字符串

    5. 多个URL

    多个URL执行同一个视图函数

    @app.route("/")
    @app.route("/index")
    def index():
        return "首页"
    

    例如

    定义路由:127.0.0.1:5000/show 127.0.0.1:5000/show/list 127.0.0.1:5000/show/<name>,执行同一个函数,返回相应的内容

    @app.route("/show")
    @app.route("/show/list")
    @app.route("/show/<name>")
    def show(name="Chancey"):
        return "show %s"% name
    

    如果在app.run()设置host=0.0.0.0

    不影响当前虚拟IP(127.0.0.1)

    可以让当前局域网中的其他计算机通过内网IP访问服务器

    二、模板

    模板是一种特殊的HTML文件,Python+HTML网页结构,允许在模板文件中使用变量,定义流程控制。使用模板可以使用视图函数专注于处理业务逻辑,将页面渲染交由模板控制

    • 导入render_template

    • 项目中创建“templates”文件夹,所有模板文件必须存放"template"文件夹下

    • 在视图函数中使用render_template("模板文件"),生成模板字符串,交由浏览器解析

    from flask import Flask,render_template
    
    app = Flask(__name__)
    
    @app.route("/info")
    def info():
        return render_template("01-show.html", name="flask", age=20)
    

    1. 变量代码块

    1. 模板中使用变量

      语法:{{ 变量名(key) }}

    2. 从视图函数中获取相关的变量,传递到模板文件中

      语法:return render_template("模板文件", key1=value1, key2=value2)

      函数中可以传递若干键值对,其中的key名就是在模板文件中使用的变量名

      local()函数,是将当前作用域中的所有局部变量打包成一个字典返回,可以用一个变量接收,然后传递到模板中.

      • 如果变量里面有字典类型的数值,有两种方法取值variable["keyName"]variable.keyName
      • 如果变量里面有列表类型的数值,则直接用list[number]取值

    例如:

    视图函数中定义变量(name="" age= dic= tub= list= ),将数据传递到模板文件中显示

    from flask import Flask, render_template
    
    # 创建实例
    app = Flask(__name__)
    
    # 定义动物类
    class Pet(object):
        name = None
        def play(self):
            return "来和" + self.name + "玩耍吧"
    
    @app.route('/show')
    
    def show():
        name = "Chancey"
        age = 18
        dic = {
            "name":"Waller",
            "age":20
        }
        list = ["开车","保健"]
        tup = ("波多","仓井","海翼")
    
        # 实例化对象
        cat = Pet()
        cat.name = "妲己"
    
        # locals() 将当前作用域中的局部变量包装成一个字典返回
    
        # key=value
        return render_template("01-show.html", d=locals())
    
    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>show</title>
    </head>
    <body>
        <h1>模板文件</h1>
        <p>列表、元组、字典都可以使用[key/index]和点语法访问</p>
        <p>name:{{ d["name"] }}</p>
        <p>age:{{ d.age }}</p>
        <p>name:{{ d.dic["name"] }}</p>
        <p>宠物名:{{ d.cat.name }}</p>
        <p>动作:{{ d.cat.play() }}</p>
    </body>
    </html>
    

    2. 过滤器

    允许模板中的变量在输出之前修改成其他的值,修改显示

    • upper转大写字母
    • lower转小写字母
    • title首字母大写
    • first获取第一个
    • last获取最后一个
    • length获取列表长度
    • default如果变量未赋值,可采用默认值
    • trim去掉字符串两边的空格
    • ....

    语法:{{ 变量|过滤器1|过滤器2 }}

    <!-- 在python文件视图函数中自行添加s1变量,赋值"   hello world" -->
    <p>原版:{{ d.s1 }}</p>
    <p>大写:{{ d.s1|upper }}</p>
    <p>小写:{{ d.s1|lower }}</p>
    <p>首字母大写:{{ d.s1|title }}</p>
    <p>获取第一个:{{ d.s1|first }}</p>
    <p>获取最后一个:{{ d.s1|last }}</p>
    <p>获取长度:{{ d.s1|length }}</p>
    <p>去掉两边空格:{{ d.s1|trim }}</p>
    <p>未赋值的变量:{{ d.s2|default("默认变量") }}</p>
    

    3. 控制代码块

    在模板中书写条件语句和循环语句,使用{% python语句 %}

    3.1 if

    {% if 条件 %}
    	条件成立时。允许书写静态标签,也可以书写变量
    {% endif %}
    
    {% if 条件 %}
    	条件成立时执行
    {% else %}
    	条件不成立时执行
    {% endif %}
    
    <!-- 多重分支 -->
    {% if 条件1 %}
    	pass
    {% elif 条件2 %}
    	pass
    {% elif 条件3 %}
    	pass
    {% endif %}
    

    例如:

        {% if d.age < 18 %}
            <h3>{{ d.age }}岁未成年</h3>
        {% elif d.age < 30 %}
            <h3>{{ d.age }}岁青成年</h3>
        {% elif d.age < 50 %}
            <h3>{{ d.age }}岁中成年</h3>
        {% else %}
            <h3>{{ d.age }}岁老年人</h3>
        {% endif %}
    

    3.2 for

    {% for 变量 in 可跌对象 %}
    {% endfor %}
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>show</title>
        <style>
        .c1{
            background: red;
        }
        .c2{
            background: orange;
        }
        .c3{
            background: cyan;
        }
        </style>
    </head>
    <body>
    <table border="2px">
        <tr>
            <td>姓名</td>
            <td>年龄</td>
        </tr>
    {% for item in info %}
        <tr
         {% if loop.first %}
            class = c1
         {% elif loop.last %}
            class = c2
         {% else %}
            class = c3
         {% endif %}
        >
            <td>{{ item.name }}</td>
            <td>{{ item.age }}</td>
        </tr>
    {% endfor %}
    </table>
    </body>
    </html>
    
    from flask import Flask, render_template
    
    app = Flask(__name__)
    
    @app.route('/')
    def show():
        info = [
            {"name":"Chancey","age":18},
            {"name":"Waller","age":35},
            {"name":"Mary","age":16},
            {"name":"Jacob","age":40},
            {"name":"William","age":17},
            {"name":"Samuel","age":37},
            {"name":"Anthony","age":35},
        ]
        return render_template("02-show.html", info=info)
    
    if __name__ == '__main__':
        app.run(debug=True, host="0.0.0.0")
    

    3.3 loop

    循环的内部变量loop:直接在内部使用,表示本次循环相关的信息

    常用属性:

    • loop.index当前循环的次数,默认从1开始计算
    • loop.index0当前循环的次数,从0开始计算
    • loop.first是否为第一次循环,值为True表示第一次循环
    • loop.last是否为最后一个循环

    实例在前边for循环中已使用

    4. 静态文件

    • 不与服务器交互的文件都是静态文件(css、js、图片、音频等)

    • 所有静态文件都必须存储在一个名为static的文件夹下,Flask程序会自动查找

    • 静态文件的访问:必须使用/static访问

    • url_for("视图函数名")实现反向解析路由,后边可以跟参数

      url_for("login")根据视图函数解析对应的URL

      url_for("login", uname="chancey", passwd="123456")反向解析带参数的路由

      /login/chancey/123

      /static/css/base.css

      <link rel="stylesheet" href="{{ url_for('static',filename='path') }}>"

    5.模板继承

    与类的继承相似

    如果两个页面中大部分内容与结构都一致,可以采用模板继承

    实现:

    • 父模板:指定可以被子模板重写的内容

      {% block 块名 %}
      	<h1>父模板</h1>
      {% endblock %}
      
    • 子模板中继承父模板

      {% extends 父模板名称 %}
      
    • 子模板中可以重写父模板中指定的块的内容

      {% block 块名 %}
      	<h1>子模板</h1>
      {% endblock %}
      
    <!--路由自行配置,不再展示-->
    <!-- 01-base.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>
            {% block web_title %}
            父模板
            {% endblock %}
        </title>
    </head>
    <body>
        <h4>
            {% block title %}
            这里是标题
            {% endblock %}
        </h4>
        <p>
            {% block content %}
            这里是内容
            {% endblock %}
        </p>
    </body>
    </html>
    
    <!--路由自行配置,不再展示-->
    <!-- 02-index.html -->
    {% extends "02-base.html" %}
    
    {% block web_title %}
     佛曰
    {% endblock %}
    
    {% block title %}
     佛曰
    {% endblock %}
    
    {% block content %}
      写字楼里写字间,写字间里程序员;
      程序人员写程序,又拿程序换酒钱。
      酒醒只在网上坐,酒醉还来网下眠;
      酒醉酒醒日复日,网上网下年复年。
      但愿老死电脑间,不愿鞠躬老板前;
      奔驰宝马贵者趣,公交自行程序员。
      别人笑我忒疯癫,我笑自己命太贱;
      不见满街漂亮妹,哪个归得程序员?
    {% endblock %}
    

    三、网络请求

    利用网络通信协议实现前后端数据交互,常用的网络通信协议:HTTP(S),规定数据的传输格式

    1. 请求

    1.1 请求消息

    客户端向服务端发送的消息

    1.2 组成

    1. 请求起始行

      协议、请求方式、资源路径

    2. 请求消息头

      使用kry-value字典的方式存储相关信息

    3. 请求主体

      get请求如果携带数据,以参数的形式直接拼接在URL后边(?key1=value1&key2=value2

      只有POST方式才会有请求主体

    2. 响应

    2.1 响应信息

    服务端接收到请求并且处理之后,返回给客户端的信息(数据)

    2.2 组成

    1. 响应起始行

      协议、响应状态码、原因短句

    2. 响应消息头

      描述响应回来的数据,以key:value存储

    3. 响应主体

      保存响应数据

    四、Flask中的HTTP

    1. requests

    在requests对象中封装了所有跟当前请求相关的信息

    使用:

    1. 引入:from flask import request

    2. 使用:在视图函数中获取request对象内部的信息

    3. 属性:

      scheme获取此次请求的协议

      method获取请求方式

      args获取GET提交的数据

      form获取POST提交的数据

      cookies获取cookies中保存的数据

      files获取上传的文件

      path获取请求的资源路径(无参数)

      full_path获取请求的资源路径(携带参数)

      url 获取完整的请求地址

      headers

    <h2>子模板</h2>
    <p>协议:{{ params.scheme }}</p>
    <p>请求方式:{{ params.method }}</p>
    <p>请求的参数:{{ params.args }}</p>
    <p>请求的参数的内容:{{ params.args.uname }}</p>
    <p>请求的参数的内容:{{ params.args.age }}</p>
    <p>cookies:{{ params.cookies }}</p>
    <p>资源路径:{{ params.path }}</p>
    <p>资源路径:{{ params.full_path }}</p>
    
    1. 获取请求中的数据

      获取GET请求中的数据

      request.args["key"]

      request.args.get("key","默认值")

      request.args.getlist("key")适用于一个key对应多个值的情况(复选框)

      print(request.args.get("uname"))
      print(request.args.get("passwd"))
      print(request.args.getlist("hobby"))
      #get当时如果未携带数据,在视图函数中直接读取request.args['']数据,报400
      

      获取POST请求中的数据

      request.form获取数据字典

      request.form["key"]

      request.form.get("key")

      request.form.getlist('key')

      
      

      post即使未携带参数,直接获取字典的值,返回为空

    2. 页面重定向

      由服务器端通知浏览器重新向新的地址发送请求

      引入redirect

      使用函数redirect("重定向地址")

      视图函数中返回return redirect("重定向地址")

    3. 页面源

      当前的请求是从哪一个源地址发起的,保存在请求消息头中("Referer":""

    4. 文件上传

      使用表单控件type="file"向服务器发送文件,因为文件,图片,音频等都是为禁止数据,必须设置表单的提交方式和编码类型

      <form action="" method="post" ectype="multipart/form-data">

      服务器端使用request.files获取上传的文件,返回字典

      例如:

      f = request.files["key"]
      f.save(保存路径)
      
      @app.route("/add", methods=["GET", "POST"])
      def add():
          if request.method == "GET":
              return render_template("02-add.html")
          else:
              title = request.form["title"]
              type = request.form["type"]
              content = request.form["content"]
              print("标题:%s 类型:%s 内容:%s"%(title, type, content))
      
              # 判断文件上传
              if "userimg" in request.files:
                  file = request.files["userimg"]
                  file_name = generate_filename(file.filename)
                  up_path = generate_upload_path(__file__, "static/upload", file_name)
                  print("保存路径:" + up_path)
                  return "获取数据成功"
              else:
                  return "已存在"
      

    2. response

    模型(Models)

    模型:根据数据表结构而创建出来的class(一张表一个类,一个字段就是一个属性)

    框架:ORM(Object Relational Mapping 对象关系映射)

    特征:

    • 数据表到编程类的映射
    • 数据类型的映射
    • 关系映射(将数据库中表与表之间的关系 对应到 编程语言中类与类的关系)

    优点:

    • 封装操作提升效率
    • 省略庞大的数据访问层

    五、ORM

    1. SQLAlchemy

    安装:pip install flask-sqlalchemy

    导包:from flask_sqlalchemy import SQLAlchemy

    配置数据库:app.config['SQLALCHEMY_DATABASE_URI']="MYSQL://用户名:密码@数据地址:端口/数据库名"

    创建数据库:create database dbname default charset utf8 collate utf8_general_ci;

    数据库自动提交:app.config["SQLALCHEMY_COMMIT_ON_TEARDOWN"] = True

    映射

    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    
    # import pymysql
    # pymysql.install_as_MySQLdb()
    
    app = Flask(__name__)
    
    #连接数据库
    app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:Asd.1234@127.0.0.1:3306/flaskDB"
    #创建SQLAlachemy实例
    db = SQLAlchemy(app)
    print(db)
    
    
    if __name__ == '__main__':
        app.run(debug=True, host="0.0.0.0")
    

    上边的代码中,import pymysql pymysql.install_as_MySQLdb()可以省略,简写在config中

    简写

    2. 定义类

    2.1 作用

    通过编写模型类的方式,让程序自动生成数据表模型类也称为实体类

    2.2 语法

    # 代码中大写单词均为自定义
    class MODELNAME(db.Model):
        __tablename__ = "TABLENAME"
        COLUMN = db.Column(db.TYPE, OPPTIONS)
        
    """
    1. MODELNAME 定义模型类名称,参考表名
    2. TABLENAME 指定要映射到的表名,如果不存在的话,则创建表
    3. COLUMN 属性名,映射到数据表中就是列名
    4. TYPE 映射到列的数据类型
    5. OPPTIONS 列选项
    """
    

    db.TYPE列类型

    数据类型对应表

    OPPTIONS列选项

    opptions

    class Usres(db.Model):
        __tablename__ = "users"
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        username = db.Column(db.String(20), nullable=False, unique=True)
        age = db.Column(db.Integer)
        email = db.Column(db.String(120), unique=True)
    
        def __init__(self, username, age, email):
            self.username = username
            self.age = age
            self.email - email
        
        def __repr__(self):
            return "<用户名:%r 年龄:%r 邮箱:%r>"%(self.username, self.age, self.email)
        
    #将创建好的实体类映射回数据库
    db.create_all()
    
    
    ## 创建Student实体类,表名student
    """
    1. id 主键 自增
    2. sname 姓名 长度30 不为空
    3. sage 年龄 整数
    4. isActive 启用状态 bool类型 默认为True
    """
    
    ## 创建Teacher类,表名teacher
    """
    1. id 主键 自增
    2. tname 姓名 长度30 不为空
    3. tage 年龄 整数
    """
    
    ## 创建Course类,表名course
    """
    1. id 主键 自增
    2. cname 课程名称 长度30
    """
    
    class Student(db.Model):
        __tablename__ = "student"
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        sname = db.Column(db.String(30), unique=True)
        sage = db.Column(db.Integer)
        isActive = db.Column(db.Boolean, default="True")
    class Teacher(db.Model):
        __tablename__ = "teacher"
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        tname = db.Column(db.String(30), unique=True)
        tage = db.Column(db.Integer)
    class Course(db.Model):
        __tablename__ = "course"
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        cname = db.Column(db.String(30), unique=True)
    

    3. 数据迁移

    3.1 定义

    将实体类的改动再次映射回数据库

    3.2 依赖于第三方库

    • Flask-script

      包:flask_script

      类:Manager

      作用:对项目进行管理(启动项目、增加管理指令)

    • flask-migrate

      包:flask_migrate

      类:Migrate(协调app和db之间的关系)、MigrateCommand(在终端中提供实体类迁移的指令)

    3.3 使用

    • 修改app.config

      #指定数据库不追踪
      app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
      # 指定启动的模式为调试模式
      app.config["DEBUG"] = True
      
    • 创建管理对象:manage = Manager(app)

    • 启动:manager.run()(但是项目的启动需在终端中执行python demo.py runserver)

    在使用了manger启动项目的时候,如需开启相关服务,如debug。。。

    在终端启动的时候加参数python demo,py runserver --host 0.0.0.0

    配置app.config:app.config["DEBUG"] = True

    • 导入from flask_migrate import Migrate, MigrateCommand
    • 在实体类之前创建migrate = Migrate(app, db)
    • 增加一个子命令manage.add_command("db", MigrateCommand)

    3.4 迁移

    • python run.py db init

      作用:执行项目和数据库的初始化操作

      特点:一个项目中只执行一次即可

    • python run.py db migrate

      作用:将编辑好的实体类生成一个中间文件并保存

      特点:只要检测到实体类有更改,就会生成中间文件

    • python run.py db upgrade

      作用:将中间文件映射到数据库

    from flask import Flask, request, render_template, url_for
    from flask_sqlalchemy import SQLAlchemy
    from flask_script import Manager
    from flask_migrate import Migrate, MigrateCommand
    
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:Asd.1234@127.0.0.1:3306/run02"
    app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
    app.config["DEBUG"] = True
    app.config["SQLALCHEMY_COMMIT_ON_TEARDOWN"] = True
    
    db = SQLAlchemy(app)
    manage = Manager(app)
    migrate = Migrate(app, db)
    manage.add_command("db", MigrateCommand)
    

    六、模型

    1. 增

    • 创建实体类对象,并为对象的属性赋值

      user = Users()

      user.username = "Chancey"

      user.age = 30

      user.isActive = True

      user.birthday = "2019-01-01"

    • 将实体对象保存回数据库对象

      db.session.add(user)

      db.session.commit(user)

    user = Users(username, age, email)
    db.session.add(user)
    db.session.commit()
    

    2. 查

    2.1 .基于db.session

    参数:要查询的列,如果查询多个列的话使用,隔开,如果要查询所有列,参数为实体类名

    2.1.1 query()

    实例:

    • 查询Users实体类中的id,username

      db.session.query(Users.id, Users.username)

    • 查询Users实体类中所有的列

      db.session.query(Users)

    • 查询Users以及wife实体类所有的列

      db.session.query(Users, Wife)

    返回值:返回一个Query对象(SQL语句)

    # 返回一个query对象
    query = db.session.query(Users.id,Users.uaername)
    print(query)
    print("type:",type(query))
    
    2.1.2 查询执行函数

    作用:在query的基础上得到最终的查询结果

    语法:db.session.query(xxx)查询执行函数()

    函数:

    • all()

      以列表的方式返回所有的数据

    • first()

      以实体对象的方式返回第一条数据,没有查询到数据则返回None

    • first_or_404()

      效果同上,没查询到结果则响应404

    • count()

      返回查询结果的数量

    s = db.session.query(Users.username, Users.age, Users.email).all()
    for i in s:
        print(i.username, i.age, i.email)
    
    user = db.session.query(Users).first()
    print(user.username, user.age, user.email)
    
    print(db.session.query(Users).count())
    
    2.1.3 查询过滤器函数

    作用:在db.session.query()追加条件

    语法:db.session.query(xx).执行函数()

    函数:

    • filter()各种各样的查询条件均可实现
    • filter_by()只做等值条件判断
    • limit()限定行数
    • offset()指定结果的偏移量
    • order_by()按照指定条件排序
    • group_by()分组查询

    返回值:均是query对象

    实例:

    • 查询年龄大于25的信息

      db.session.query(Users).filter(Users.age>25).all()

    • 查询id为2的User信息

      db.session.query(Users).filter(Users.id==2).first()

    • 查询idActive为true并且年龄大于30的

      db.session.query(Users).filter(Users.isActive==True).filter(Users.age>30).all()

    • 获取前5条数据

      db.session.query(Users).limit(5).all()

    • 对表中的所有数据按照id倒序排序

      db.session.query(Users).order_by("id desc").all()

    (1) or_

    导入:from sqlalchemy improt or_

    使用:

    查询isActive为True或者年龄不小于30的

    db.session.query(User).filter(or_(User.isActive==True,User.age>=30)).all()

    (2) like

    模糊查询like主要使用实体类属性所提供的的like()函数

    查询email中包含an的信息

    db.session.query(Users).filter(Users.email.like("%an%")).all()

    (3) in_

    模糊查询in,需要使用实体类提供的属性in_函数完成

    查询年龄是30、17、45的*

    db.session.query(Users).filter(Users.age.in_([30,17,45])).all()

    (4) between

    模糊查询between...and...需要使用实体类属性提供的between(值1,值2)

    查询年龄在30到45之间的

    db.session.query(Users).filter(Users.age.between(30,45)).all()

    2.2 基于Models

    Models.query.查询过滤(条件参数).查询执行函数()

    例如:Users.query.filter(Users.id>3).all()

    3. 删除

    • 查询出要删除的实体user = db.session.query(Users).filter_by(id=5).first()
    • 根据所提供的删除方法将信息删除db.session.delete(user)
    • 提交(使用manger可自动提交)db.session.commit()
    @app.route('/delete')
    def delete_view():
        id = request.args.get("id")
        user = Users.query.filter_by(id=id).first()
        db.session.delete(user)
    
        url = request.headers.get("referer", '/query_all')
        return redirect(url)
    

    4.修改

    • 保存
    user = Users.query.filter_by(id=5).first()
    user.uaername = "老杨"
    user.passwd = "abcdefg"
    return "修改成功"
    
    @app.route('/update', methods=["GET", "POST"])
    def update_view():
        if request.method == "GET":
            id = request.args.get('id') # 获取前端传过来的id
            user = Users.query.filter_by(id = id).first() # 根据id查询出对应的实体对象
            return render_template("03-update.html", u = user)# 将实体对象放到前端页面显示
        else:
            id = request.form['id']
            username = request.form["username"]
            passwd = request.form["passwd"]
    
            user = Users.query.filter_by(id = id).first() #查
    
            user.uaername = username # 改
            user.passwd = passwd # 改
    
            db.session.add(user) # 保存
    
            return redirect("/info?tiaojian=")
    
  • 相关阅读:
    MS SQL Server 定时任务实现自动备份
    Python日期的加减等操作
    C# DbHelperSQL 类,从东软生成器提取而来
    C# List<string>和ArrayList用指定的分隔符分隔成字符串
    自定义可视化调试工具(Microsoft.VisualStudio.DebuggerVisualizers)
    查看SQLServer最耗资源时间的SQL语句
    程序员不适合创业
    如何写高质量,不繁琐的会议记录?
    C#中的Attribute详解(下)
    微信小程序教程系列
  • 原文地址:https://www.cnblogs.com/chancey/p/11450947.html
Copyright © 2020-2023  润新知