zoukankan      html  css  js  c++  java
  • day94:flask:Jinjia2模板引擎&flask中的CSRF攻击&Flask-SQLAlchemy的创建模型类和基本的增删改查

    目录

    1.Jinjia2模板引擎

      1.Jinjia2加载模板并传递数据到模板中

      2.Jinjia2的模板语句

      3.模板中特有的变量和函数

      4.模板中内置的过滤器

      5.自定义过滤器

      6.模板继承

    2.在flask中解决CSRF攻击

    3.Flask-SQLAlchemy

      1.Flask-SQLAlchemy简单介绍

      2.安装

      3.数据库连接设置

      4.创建模型类

      5.数据基本操作:增删改查

    1.Jinjia2模板引擎

    1.Jinjia2加载模板并传递数据到模板中

    1.设置template_folder参数

    2.设置data:

    data["num"] = 100

    3.传递data到模板:

    return render_template( "index1.html", **data )
    from flask import Flask,render_template
    
    # 设置template_folder参数,创建template目录
    app = Flask(__name__,template_folder="templates")
    
    @app.route("/")
    def index():
        data = {}
        data["title"] = "我的第一个flask网页"
        data["num"] = 100
        # - render_template 函数的第一个参数是模板的文件名,后面的参数都是键值对,表示模板中变量对应的真实值。
        return render_template( "index1.html", **data )
    
    if __name__ == '__main__':
        app.run(debug=True)
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>{{title}}</h1>
        <p>num={{num}}</p>
    </body>
    </html>

    2.Jinjia2的模板语句

    from flask import Flask,render_template
    
    app = Flask(__name__,template_folder="templates")
    
    @app.route("/")
    def index():
        data = {}
    
        # 1.字典
        data["info"] = {
            "name":"xiaoming",
            "age":19,
            "sex":True,
            "class": "1009"
        }
    
        # 2.列表
        data["student_list"] = ["xiaoming","xiaobai","xiaohei","xiaoan"]
    
        # 3.列表内嵌套字典
        data["goods_list"] = [
            {"id":10,"name":"Python7天入门到放弃","price":99.9,"num":100},
            {"id":11,"name":"Python3天入门到放弃","price":99.9,"num":100},
            {"id":12,"name":"Python5天入门到放弃","price":99.9,"num":100},
            {"id":13,"name":"Go7天入门到放弃","price":99.9,"num":100},
            {"id":14,"name":"Go5天入门到放弃","price":99.9,"num":100},
            {"id":15,"name":"Linux7天入门到放弃","price":99.9,"num":100},
        ]
    
        return render_template( "index2.html", **data )
    
    if __name__ == '__main__':
        app.run(debug=True)

    1.访问字典数据中的成员

    访问字典数据中的成员,可以通过中括号取值或者点[.]取值

        <p>访问字典数据中的成员</p>
        <p>{{ info["name"] }}</p>
        <p>{{ info.name }}</p>

    2.访问列表数据中的成员

    访问列表数据中的成员,可以通过中括号索引取值或者点[.]取值

    但是要注意:点[.]语法不支持负数下标

        <p>{{ student_list.0 }}</p>
        <p>{{ student_list.2 }}</p>
        <p>{{ student_list[-1] }}</p>
        <p>{{ student_list[2] }}</p>

    3.模板中的if循环

     <p>if判断</p>

    <!-- 1.只有if循环 --> {% if info.age < 18 %} <p>小明请出去</p> {% endif %}
    <!-- 2.if+else --> {% if info.age > 10 %} <p>小明同学</p> {% else %} <p>小明小朋友</p> {% endif %}
    <!-- 3.if+elif+else --> {% if info.age < 10 %} <p>小明小朋友</p> {% elif info.age < 18 %} <p>小明同学</p> {% else %} <p>大明同学</p> {% endif %}

    4.模板中的for循环

    <p>for循环</p>
        <!-- 1.for+if/else -->
        <ul>
            {% for student in student_list %}
                {% if loop.last %}
                <li style="background-color:#000;color:#fff;">{{ student }}</li>
                {% else %}
                <li>{{ student }}</li>
                {% endif %}
            {% endfor %}
        </ul>

    5.for循环中的loop用法

    loop 是jinja模板引擎提供给开发者获取循环中的信息对象 

    loop.index 显示本次循环的次数,从1开始 
    loop.index0 显示本次循环的次数,从0开始 
    loop.first 显示本次是否属于循环的第一次,是则为真 

      <!-- 2.for循环中loop的用法 -->
            {% for goods in goods_list %}
                {% if loop.index % 2 %}
                <tr bgcolor="#00bfff">
                {% else %}
                <tr>
                {% endif %}
                    <td>{{ loop.index0 }}</td>
                    <td>{{ goods.id }}</td>
                    <td>{{ goods.name }}</td>
                    <td>{{ goods.price }}</td>
                    <td>{{ goods.num }}</td>
                </tr>
            {% endfor %}

    3.模板中特有的变量和函数

    模板中特有的变量和函数:config,request,g变量,session,url_for()

    from flask import Flask,render_template,session
    
    app = Flask(__name__,template_folder="templates")
    
    app.config["SECRET_KEY"] = "1234asda"
    
    @app.route("/")
    def index():
        data = {}
        session["name"]="xiaohuihui" # 设置内置变量
        return render_template( "index3.html", **data )
    
    if __name__ == '__main__':
        app.run(debug=True)
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <!-- 获取上下文对象 -->
        <p>{{ request.url }}</p> <!-- 获取当前请求url -->
        <p>{{ request.method }}</p> <!-- 获取当前请求方法 -->
    
        <p>{{ session }}</p> <!-- 获取session对象 -->
        <p>{{ session.name }}</p> <!-- 获取session指定键对应的值 -->
    
        <p>{{ config.DEBUG }}</p> <!-- 获取flask配置的debug的值 -->
    
        <p>{{ url_for("index") }}</p> <!-- 获取url中后面的参数 -->
    
    </body>
    </html>

    4.模板中内置的过滤器

    from flask import Flask,render_template,session
    
    app = Flask(__name__,  # 当前flask应用运行的模块
                static_folder="static", # 当前flask应用保存静态资源[css/js/img/音视频]
                static_url_path="/lib", # 当前flask应用提供给外界访问的路径前缀,必须以/开头
                template_folder="templates"
        )
    
    app.config["SECRET_KEY"] = "1234asda"
    
    @app.route("/")
    def index():
        data = {}
        data["message"] = "hello,python, after 7 day, byebye"
        data["images"] = "<img src='/lib/images/1.jpg'>"
        return render_template( "index4.html", **data )
    
    if __name__ == '__main__':
        app.run(debug=True)
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
        img{
            width: 100px;
        }
        </style>
    </head>
    <body>
        <p>{{ message | upper }}</p>  <!-- 变为大写 -->
        <p>{{ images | safe }}</p> <!-- 禁用转义 -->
        <p>{{ message | reverse | upper }}</p> <!-- 链式调用过滤器 -->
        <p>{{ '<em>hello</em>' | striptags }}</p>
        <p>{{ "如果x<y,z>x,那么x和z之间是否相等?" | striptags }}</p> <!-- 渲染之前把所有的html标签都删除掉 -->
        <p>{{ '床前明月光,疑是地上霜。' | truncate(5,False,'...', 0)}}</p> <!-- 字符串截断 -->
    
        <p>{{ [1,1,2,3,4,5,1,2,2,3,4] | unique | list }}</p> <!-- 列表去重 -->
    </body>
    </html>

    5.自定义过滤器

    from flask import Flask,render_template
    
    app = Flask(__name__,  # 当前flask应用运行的模块
                static_folder="static", # 当前flask应用保存静态资源[css/js/img/音视频]
                static_url_path="/lib", # 当前flask应用提供给外界访问的路径前缀,必须以/开头
                template_folder="templates"
        )
    
    app.config["SECRET_KEY"] = "1234asda"
    
    # 1.自定义过滤器函数
    def do_mobile(content):
        return content[:3]+"*****"+content[-3:]
    
    # 2.将过滤器函数添加到template_filter中
    app.add_template_filter(do_mobile,"mobile")
    
    @app.route("/")
    def index():
        data = {}
        data["mobile_list"] = [
            "13513241123",
            "13513241123",
            "13513241123",
            "13513241123",
            "13513241123",
        ]
        return render_template( "index5.html", **data )
    
    if __name__ == '__main__':
        app.run(debug=True)
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        {% for mobile in mobile_list %}
        <p>{{ mobile | mobile }}</p> <!-- 使用自定义过滤器 -->
        {% endfor %}
    </body>
    </html>

    6.模板继承

    from flask import Flask,render_template
    
    app = Flask(__name__,  # 当前flask应用运行的模块
                template_folder="templates"
        )
    
    @app.route("/")
    def index():
        data = {}
        return render_template( "index6.html", **data )
    
    if __name__ == '__main__':
        app.run(debug=True)

    base.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{% block title %} 父级模板的内容 {% endblock %}</title>
        {% block hander %} {% endblock hander %}
    </head>
    <body>
        {% block content %}
            <p>父级模板的content</p>
        {% endblock content %}
    </body>
    </html>

    index6.html

    {% extends "base.html" %}
    
    {% block title %}来自子模板的标题{% endblock title %}
    
    {% block hander %}
        <script>
        alert(1)
        </script>
    {% endblock hander %}
    
    {% block content %}
        {{ super() }}
        <p>子模板的内容</p>
        {{ super() }}
    {% endblock %}

    2.在flask中解决CSRF攻击

    1.安装

    pip3 install flask_wtf

    2.flask-wtf使用步骤

    1.设置应用程序的 secret_key,用于加密生成的 csrf_token 的值

    # 1. session加密的时候已经配置过了.如果没有在配置项中设置,则如下:
    app.secret_key = "#此处可以写随机字符串#"
    
    # 2. 也可以写在配置类中。
    class Config(object):
        DEBUG = True
        SECRET_KEY = "dsad32DASSLD*13%^32"
        
    """加载配置"""
    app.config.from_object(Config)

    2.导入 flask_wtf.csrf 中的 CSRFProtect 类,进行初始化,并在初始化的时候关联 app

    from flask.ext.wtf import CSRFProtect
    csrf = CSRFProtect(app)

    3.在表单中使用 CSRF 令牌

    <form method="post" action="/">
        <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
    </form>

    3.使用CSRF完成简单的登录

    from flask import Flask,render_template,request
    from flask_wtf import CSRFProtect
    app = Flask(__name__,  # 当前flask应用运行的模块
                template_folder="templates"
        )
    
    csrf = CSRFProtect(app)
    
    app.config["SECRET_KEY"] = "1234asda"
    
    @app.route("/")
    def index():
        data = {}
        return render_template( "index7.html", **data )
    
    @app.route("/login",methods=["POST"])
    def login():
        print(request.form)
        return "ok"
    
    if __name__ == '__main__':
        app.run(debug=True)
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <form action="{{ url_for('login') }}" method="post">
            <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" >
            账号: <input type="text" name="username" value=""><br><br>
            密码: <input type="password" name="password" value=""><br><br>
            <input type="submit" value="登录">
        </form>
    </body>
    </html>

    3.Flask-SQLAlchemy

    1.Flask-SQLAlchemy简单介绍

    flask默认提供模型操作,但是并没有提供ORM,所以一般开发的时候我们会采用flask-SQLAlchemy模块来实现ORM操作。

    SQLAlchemy是一个关系型数据库框架,它提供了高层的 ORM 和底层的原生数据库的操作。flask-sqlalchemy 是一个简化了 SQLAlchemy 操作的flask扩展。

    SQLAlchemy: https://www.sqlalchemy.org/

    中文文档: https://www.osgeo.cn/sqlalchemy/index.html

    2.安装

    1.安装 flask-sqlalchemy【清华源】

    pip install flask-sqlalchemy -i https://pypi.tuna.tsinghua.edu.cn/simple

    2.如果连接的是 mysql 数据库,需要安装 mysqldb 驱动

    pip install flask-mysqldb -i https://pypi.tuna.tsinghua.edu.cn/simple

    3.安装flask-mysqldb时,注意

    # 安装 flask-mysqldb的时候,python底层依赖于一个底层的模块 mysql-client模块
    # 如果没有这个模块,则会报错如下:
    
    Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-21hysnd4/mysqlclient/

    解决方案:

    sudo apt-get install libmysqlclient-dev python3-dev
    
    # 运行上面的安装命令如果再次报错如下:
       dpkg 被中断,您必须手工运行 ‘sudo dpkg --configure -a’ 解决此问题。
    
    # 则根据提示执行命令以下命令,再次安装mysqlclient
        sudo dpkg --configure -a
        apt-get install libmysqlclient-dev python3-dev
    
    # 解决了mysqlclient问题以后,重新安装 flask-mysqldb即可。
    pip install flask-mysqldb -i https://pypi.tuna.tsinghua.edu.cn/simple

    3.数据库连接设置

    from flask import Flask,render_template,request
    from flask_sqlalchemy import SQLAlchemy
    app = Flask(__name__)
    
    class Config():
        DEBUG = True
    # 数据库链接配置 # SQLALCHEMY_DATABASE_URI = "mysql://账号:密码@IP/数据库名?编码" SQLALCHEMY_DATABASE_URI = "mysql://root:123@127.0.0.1:3306/students?charset=utf8mb4"

    # 动态追踪修改设置,如未设置只会提示警告 SQLALCHEMY_TRACK_MODIFICATIONS = True

    # 查询时会显示原始SQL语句 SQLALCHEMY_ECHO = True app.config.from_object(Config) db = SQLAlchemy() # 初始化数据库操作对象 db.init_app(app) # 初始化数据库连接

    4.创建模型类

    from flask import Flask,render_template,request
    from flask_sqlalchemy import SQLAlchemy
    app = Flask(__name__)
    
    class Config():
        ......
    
    app.config.from_object(Config)
    
    db = SQLAlchemy() # 初始化数据库操作对象
    db.init_app(app) # 初始化数据库连接
    
    """创建模型类""" class Student(db.Model): __tablename__ = "tb_student" id = db.Column(db.Integer, primary_key=True,comment="主键ID") name = db.Column(db.String(250), comment="姓名") age = db.Column(db.Integer, comment="年龄") sex = db.Column(db.Boolean, default=False, comment="性别") money = db.Column(db.DECIMAL(8,2), nullable=True, comment="钱包") def __repr__(self): return self.name class Teacher(db.Model): __tablename__ = "tb_teacher" id = db.Column(db.Integer, primary_key=True, comment="主键ID") name = db.Column(db.String(250), comment="姓名") sex = db.Column(db.Boolean, default=False, comment="性别") option = db.Column(db.Enum("讲师","助教","班主任"), default="讲师", comment="教职") def __repr__(self): return self.name class Course(db.Model): __tablename__ = "tb_course" id = db.Column(db.Integer, primary_key=True, comment="主键ID") name = db.Column(db.String(250), unique=True, comment="课程名称") price = db.Column(db.Numeric(6, 2)) def __repr__(self): return self.name @app.route("/") def index(): return "Ok" if __name__ == '__main__': with app.app_context(): db.create_all() # 根据模型创建所有的数据表 db.drop_all() # 删除模型对应的所有数据表 app.run()

    5.数据基本操作:增删改查

    1.添加一条数据

    1.模型类实例对象

    2.add

    3.commit

    student1 = Student(name="小明", sex=True, age=17, email="123456@qq.com", money=100)
    db.session.add(student1)
    db.session.commit()
    
    # 再次插入一条数据
    student2 = Student(name='小红', sex=False, age=13, email="16565666@qq.com", money=600)
    db.session.add(student2)
    db.session.commit()

    2.添加多条数据

    用add_all+commit

    st1 = Student(name='wang',email='wang@163.com',age=22)
    st2 = Student(name='zhang',email='zhang@189.com',age=22)
    st3 = Student(name='chen',email='chen@126.com',age=22)
    st4 = Student(name='zhou',email='zhou@163.com',age=22)
    st5 = Student(name='tang',email='tang@163.com',age=22)
    st6 = Student(name='wu',email='wu@gmail.com',age=22)
    st7 = Student(name='qian',email='qian@gmail.com',age=22)
    st8 = Student(name='liu',email='liu@163.com',age=22)
    st9 = Student(name='li',email='li@163.com',age=22)
    st10 = Student(name='sun',email='sun@163.com',age=22)
    db.session.add_all([st1,st2,st3,st4,st5,st6,st7,st8,st9,st10])
    db.session.commit()

    3.删除数据

    1.query+delete+commit

    2.query.filter.delete()+commit 

    # 方法1
    student = Student.query.first()
    db.session.delete(student)
    db.session.commit()
    
    # 方法2【事务中使用,就是乐观锁】
    ret = Student.query.filter(Student.name=='sun').delete()
    db.session.commit()

    4.更新数据

    # 方法1
    student = Student.query.first()
    student.name = 'dong' # 直接通过对象.属性 来修改值
    db.session.commit()
    
    # 方法2【事务中使用,就是乐观锁】
    ret = Student.query.filter(Student.name == 'liu').update({'money': 1000})
    db.session.commit()
    
    # 方法3【批量操作, 实现类似django里面F函数的效果】
    ret = Student.query.filter(Student.age == 22).update({Student.money: Student.money+'200'})
    db.session.commit()
  • 相关阅读:
    20145220&20145209&20145309信息安全系统设计基础实验报告(1)
    20145309信息安全系统设计基础第8周学习总结下
    20145309信息安全系统设计基础第8周学习总结上
    20145309信息安全系统设计基础第7周学习总结下
    20145309信息安全系统设计基础第7周学习总结上
    20145309信息安全系统设计基础第6周学习总结下
    第六周学习总结1
    20145309 《信息安全系统设计基础》第5周学习总结
    20145309信息安全系统设计基础第3周学习总结
    20145306 信息安全系统设计基础 第五周博客总结
  • 原文地址:https://www.cnblogs.com/libolun/p/14025774.html
Copyright © 2011-2022 走看看