美文网首页flask的学习
02-Flask之模板&模型

02-Flask之模板&模型

作者: EndEvent | 来源:发表于2018-07-09 18:12 被阅读1790次

    一、模板

    • 模板概念
    - 模板是呈现给用户的界面
    
    - 在MVT中充当T的角色,实现了VT的解耦
    
    - 模板处理分两个过程
        加载
        渲染
        
    - 模板代码包含两部分
        静态HTML
        动态插入的代码
    
    • Jinja2
    - Flask中使用的是Jinja2模板引擎
    
    - Jinja2由Flask作者开发
        现代化设计和友好的python模板语言
        模仿Django的模板引擎
        
    - Jinja2官方文档
        http://jinja.pocoo.org/docs/2.10/
        
    - 优点
        速度快,被广泛使用
        HTML设计和后端python分离
        减少python复杂度
        非常灵活、快速、安全
        提供了控制,继承等高级功能
    
    • 模板语法
    - 模板语法分两种
        变量
        标签
        
    - 模板中的变量 {{ var }}
        视图传递给模板的数据
        前面定义的数据
        变量不存在,默认忽略
        
    - 模板中的标签 {% tag %}
        控制逻辑
        使用外部表达式
        创建变量
        宏定义
    
    • 结构标签 block
    语法:
        {% block xxx %}
        {% endblock %}
        
    例如:
        {% block extcss %}
        {% endblock %}
        
    用途:
        父模板挖坑,子模板填坑(块操作)
    
    • 静态资源的加载
    # 方式一: 直接写
    <link rel="stylesheet" href="/static/css/main.css">
    
    # 方式二: 通过反向解析
    <link rel="stylesheet" href={{ url_for('static',filename='css/main.css') }}>
    
    • 结构标签 extends
    语法:
        # 模板继承
        {% extends 'xxx' %}
        # 继承后需要保留块中的内容
        {{ super() }}
        
    例如:
        {% extends 'base_main.html' %}
        {% block extcss %}
            # 保留父模板中 extcss块 中内容
            {{ super() }}
            # 新添加内容
            <link rel="stylesheet" href={{ url_for('static',filename='css/index.css') }}>
        {% endblock %}
        
    用途: 
        模板继承
        挖坑继承体现的是化整为零的操作
    
    • 结构标签 include
    语法:
        {% include 'xxx.html' %}
        
    例如:
        {% include 'index_content.html' %}
        
    用途:
        包含,将其他html包含进来,体现了由零到一的概念
    

    可以将区块代码抽离到新文件;可以将重复小模块抽取,反复使用。

    • 宏定义 marco
    语法:
        {% macro fn(arg) %}
        {% endmacro %}
        
    例如(不带参数):
        # 定义
        {% macro say() %}
            <h3>今天高温预警,40℃。</h3>
        {% endmacro %}
        # 调用
        {{ say() }}
        
    例如(带参数):
        # 定义
        {% macro create_item(id,name) %}
            <P>
                <i>{{ id }}</i>
                <span>{{ name }}</span>
            </P>
        {% endmacro %}
        # 调用
        {{ create_item(student.id,student.name) }}
        
    例如(宏定义可导入from):
        {# appmacro.html文件 #}
        {% macro create_user(name) %}
            <h3>用户: {{ name }}</h3>
        {% endmacro %}
        
        {# 导入 #}
        {% from 'appmacro.html' import create_user %}
        
        {# 调用#}
        {{ create_user('风吹裤裆凉飕飕') }}
        
    用途:
        宏定义,可以在模板中定义函数,在其他地方调用
    

    备注: 可以专门创建一个页面来写宏定义,需要就引入即可。

    • 条件控制 if
    语法:
        {% if 条件 %}
            代码块
        {% elif 条件 %}
            代码块
        ...
        {% else %}
            代码块
        {% endif %}
    例如:
        {% if name and name == 'admin'  %}
            <h1>This is admin console</h1>
        {% elif name %}
            <h1>Welcome {{ name }}!</h1>
        {% else %}
            <h1>Please login</h1>
        {% endif %}
    
    • 循环控制 for
    语法:
        {% for item in items %}
            {{ item }}
        {% endfor %}
        
        {% for item in items %}
            {{ item }}
        {% else %}
            # items为空时调用
        {% endfor %}
        
    例如:
        {% for student in students %}
            {% if loop.first %}
                <p style="color: red;">{{ loop.index }}-{{ student.name }}</p>
            {% endif %}
    
            <p style="color: blue;">{{ loop.index }}-{{ student.name }}</p>
    
            {% if loop.last %}
                <p style="color: purple;">{{ loop.index }}-{{ student.name }}</p>
            {% endif %}
        {% else %}
            <p>没有数据了</p>
        {% endfor %}
        
    其他(loop循环信息):
        loop.index 循环迭代计数(从1开始)
        loop.index0 循环迭代计数(从0开始)
        loop.revindex 循环迭代倒序计数(从len开始,到1结束)
        loop.revindex0 循环迭代倒序计数(从len-1开始,到0结束)
        loop.first 是否为循环的第一个元素
        loop.last 是否为循环的最后一个元素
        loop.length 循环序列中元素的个数
    
    • 过滤器
    语法:
        {{ 变量 | 过滤器 | 过滤器 }}
    
    例如:
        {# 当变量未定义时,显示默认字符串,可以缩写为d #}
        <p>{{ name | default('No name') }}</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>
        
        {# 四舍五入取整,返回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>
        
    其他: 
        default 默认值
        capitalize 首字母大写
        lower 全小写
        upper 全大写
        trim 去除空格
        reverse 反转
        format 格式化输出
        safe 关闭转义(已审查,没有安全隐患)
        striptags 将值中标签去掉
        round 四舍五入(截取)
        abs 绝对值
        first 第一个元素
        last 最后一个元素
        length 列表长度
        sum 列表求和
        sort 列表排序(升序)
        join 合并字符串
    

    二、模型基本操作

    • 模型概念
    - Flask默认并没有提供任何数据库操作API
    - 我们可以选择任何适合自己项目的数据库来使用
    - Flask数据库操作,可以使用原生SQL语句,也可以使用ORM(SQLAlchemy,MongoEngine)
    - 原生SQL缺点
        代码利用率低,条件复杂代码语句越长,有很多相似语句;
        一些SQL是在业务逻辑中拼出来的,修改需要了解业务逻辑,直接写SQL容易忽视SQL问题;
    
    • 对象关系映射 ORM
    用于实现面向对象编程语言里不同类型系统的数据之间的转换。
    将对象的操作转换为原生SQL。
    - 易用性,可以有效减少重复SQL
    - 性能损耗少
    - 设计灵活,可以轻松实现复杂查询
    - 移植性好
    

    python的ORM(SQLAlchemy)

    • python中的SQLAlchemy安装
    # 其实是安装了SQLAlchemy, flask-sqlalchemy
    pip install flask-sqlalchemy
    
    # flask-sqlalchemy 官网
    http://flask-sqlalchemy.pocoo.org/2.3/
    
    • flask-sqlalchemy初始化
    - app/models.py文件中
        from flask_sqlalchemy import SQLAlchemy
        # 实例化对象,但还需要在__init__.py进行初始化
        db = SQLAlchemy()
    
    - app/__init.py__文件中
        from app.models import db
        # 数据库连接配置(SQLite相对简单)
        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///sqlite3.db'
        
        # 初始化
        db.init_app(app)
    

    启动项目时报出警告,如果不需要可以将对应配置SQLALCHEMY_TRACK_MODIFICATIONS为False即可,以减少对象追踪修改的系统开销。

    • 定义模型
    class Student(db.Model):
        # 如果想要改表名
        __tablename__ = 'Worker'
        s_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        s_name = db.Column(db.String(20))
        s_age = db.Column(db.Integer)
    

    flask模型中,主键需要自己定义,否则会报错(每个模型对应一个表单,每个表单都需要一个主键)!

    • 创建表单
    db.create_all()
    
    • 删除表单
    db.drop_all()
    
    • 插入数据
    stu = Student()
    stu.s_name = '%d-测试' % random.randrange(10000)
    stu.s_age = random.randrange(1,100)
    
    db.session.add(stu)
    db.session.commit()
    
    • 查询数据
    # 获取对应表单中所有数据
    tudents = Student.query.all()
    

    三、模型之数据库

    • 数据库连接
    dialect+driver://username:password@host:port/database
        dialect 数据库
        driver 数据库的驱动
        username 数据库用户名
        password 数据库密码
        host 数据主机
        port 数据库端口号
        database 连接数据库名
    

    SQLite数据库连接不需要额外驱动,也不需要用户名和密码

    • 连接数据库指定配置
    # 即上述内容
    app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI
    # 禁止对象追踪修改
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False  
    
    • 连接MySQL
    - 系统中安装有MySQL
    
    - MySQL连接驱动
        pip install pymysql
        
    - MySQL中创建对应的数据库
        create database HelloFlask charset=utf8;
        
    - 连接数据库配置
        app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@localhost:3306/HelloFlask'
        
    - 其他操作都是一样(就是数据库不同而已)
    

    四、项目拆分

    - 扩展的 ext.py
        
    - 配置的 settings.py
    
    项目拆分
    规划项目结构

    相关文章

      网友评论

        本文标题:02-Flask之模板&模型

        本文链接:https://www.haomeiwen.com/subject/gtituftx.html