Flask-day02

2019-01-10  本文已影响0人  陈small末

一、模板

- 模板是呈现给用户的界面

- 在MVT中充当T的角色,实现了VT的解耦

- 模板处理分两个过程
    加载
    渲染

- 模板代码包含两部分
    静态HTML
    动态插入的代码

- Flask中使用的是Jinja2模板引擎

- Jinja2由Flask作者开发
    现代化设计和友好的python模板语言
    模仿Django的模板引擎

- Jinja2官方文档
    http://jinja.pocoo.org/docs/2.10/

- 优点
    速度快,被广泛使用
    HTML设计和后端python分离
    减少python复杂度
    非常灵活、快速、安全
    提供了控制,继承等高级功能

- 模板语法分两种
    变量
    标签

- 模板中的变量 {{ var }}
    视图传递给模板的数据
    前面定义的数据
    变量不存在,默认忽略

- 模板中的标签 {% tag %}
    控制逻辑
    使用外部表达式
    创建变量
    宏定义

语法:
    {% 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 'xxx' %}
    # 继承后需要保留块中的内容
    {{ super() }}

例如:
    {% extends 'base_main.html' %}
    {% block extcss %}
        # 保留父模板中 extcss块 中内容
        {{ super() }}
        # 新添加内容
        <link rel="stylesheet" href={{ url_for('static',filename='css/index.css') }}>
    {% endblock %}

用途: 
    模板继承
    挖坑继承体现的是化整为零的操作

语法:
    {% include 'xxx.html' %}

例如:
    {% include 'index_content.html' %}

用途:
    包含,将其他html包含进来,体现了由零到一的概念

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

语法:
    {% 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 条件 %}
        代码块
    {% 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 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问题;

用于实现面向对象编程语言里不同类型系统的数据之间的转换。
将对象的操作转换为原生SQL。
- 易用性,可以有效减少重复SQL
- 性能损耗少
- 设计灵活,可以轻松实现复杂查询
- 移植性好

python的ORM(SQLAlchemy)

# 其实是安装了SQLAlchemy, flask-sqlalchemy
pip install flask-sqlalchemy

# flask-sqlalchemy 官网
http://flask-sqlalchemy.pocoo.org/2.3/

- 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连接驱动
    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

image image
上一篇下一篇

猜你喜欢

热点阅读