Flask04_模板语法

#encoding=utf-8
"""
1、创建web服务器实例:app = Flask(__name__,template_folder,static_folder)
(1)__name__:内置方法,是模块的名称或者包的名称,确定应用的路径
    A、默认的值直接执行当前文件:__name__="__main__"(直接执行文件|被导入执行)
    B、修改被导入文件的相对路径:__name__="文件的相对路径"(指执行的优先级)
(2)template_folder:指定前端页面的存放路径
    A、默认网页html文件的目录,在当前文件的同级目录的templates目录下
    B、通过template_folder="文件路径/templates"可以配置html网页的查找目录
(3)static_folder:指定静态文件的存放路径
    A、默认静态文件的目录,在当前文件的同目录下的static目录下,可以通过配置项更改模板文件和静态文件的存放目录
    B、可以通过static_folder="文件路径/static"可以配置静态文件的查找目录
(4)app就是一个程序实例
    A、客户端(一般是浏览器)将请求发送给服务端Web服务器
    B、Web服务器再把请求发给Flask实例
(5)Flask的配置文件
    A、app属性的方式:app.debug=True
    B、app.config字典形式:app.config["DEBUG"] =True
    C、py文件作为配置文件,settings.py中写配置代码:app.config.from_pyfile("setting.py")
    D、以类的形式,推荐使用:app.config.from_object("settingobj.TestConfig")
    >> settingsobj是独立的py文件,在文件中以类的形式定义配置,需要使用配置时直接settingobj.类名就可以
        class Config:
            DEBUG = False
        class ProductConfig(Config):
            pass
        class TestConfig(Config):
            DEBUG =  True
(5)更多参数参考__doc__:print(Flask.__doc__)
2、Jinja2模板技术
(1)直接在视图中定义HTML结构数据是十分困难的,可以使用外部的HTML文件加载来渲染页面
(2)jinja2模块给flask提供了加载html页面的能力,可以使用jianjia2的语法来直接使用已经写好的HTML页面
(3)render_template方法:  自动的加载当前路径下的templates下的同名html,然后将html返回到浏览器
(4)可以将视图当中的数据渲染到前台页面上,少量数据可以用键=值的形式进行传参到前端
(5)大量/较多数据时,可以使用**locals()的方式,一次性将所有数据传送到前端页面,Locals是对局部变量整合的字典
(6)模板引擎负责MVC中的V(view视图)部分
    A、Flask本身不带模板系统,默认使用Python开发的Jinja2模板引擎
    B、Jinja2是Django模板系统的仿制品,功能却更为完善
    C、现Django可以舍弃自己的模板系统,可以采用Jinja2系统
(7)前端静态文件
    A、服务器上将前端资源分为静态资源和动态资源,全栈开发中css、js、img等非html内容看作静态内容
    B、可以在创建web服务器实例中设置HTML文件存储目录和静态文件存储目录
    C、静态资源:本身内容不会发生修改,服务器会将静态资源放到某个位置上,直接加载
    D、动态资源:根据不同交互情况发生修改(数据库数据)
(8)页面加载
    A、返回数据模块:from flask import render_template
    B、在main文件同级目录创建templates目录,编写html文件
    C、默认查找加载当前目录/指定目录下的templates目录中的html
    D、导入使用render_template方法,加载返回html页面
    E、函数处理数据,将加载的内容通过模板语法渲染到页面上
(9)数据渲染:把视图函数当中的数据传递到html页面上
    A、数据以字典方式返回:return render_template("html文件",name="杜迅")
    B、数据以全部形式返回:return render_template("html文件",**locals())
3、静态加载
(1)静态资源一般不放在数据库中,而是直接放在服务器上
(2)通常在数据库当中保存的是图片/其他静态资源的地址,而资源本身放在服务器上,以便减小数据库的存储空间
(3)当前HTML页面中的所有数据都是直接写在页面内部的,若想加入图片/外部样式文件是加载不上的,需要配置static静态资源
(4)静态文件需要放在默认的静态位置(配置静态资源路径下的static目录),在html中默认使用/static/为资源的根路径
(5)开发过程中,一般后端工程师会直接使用前端写好了的静态HTML页面,后端工程师需要将静态资源内容加载到项目当中
(6)静态加载步骤
    A、静态准备:在项目目录下创建static来存放静态文件(默认),创建templates来存放模板文件(默认)
    B、静态文件:将已经开发好的静态文件(非html)复制到static
    C、开发页面:将要开发的页面放入到templates目录当中
    D、脚本创建:创建flask脚本,使用render_templates加载页面(加载开发页面)
    E、修改路径:页面的静态资源地址和服务器需要的路由地址不相符,需要进行修改,将所有静态资源地址替换为指定路由路径
    F、a链接:所有的href路由指向是错误的,需要进行修改,只需按照访问地址,使用恰当的路由替换即可
4、JinJa2模板使用
(1)模板基础
    A、直接修改HTML页面时,会出现大量的重复性的加载引入,会出现代码冗余、开发效率低等问题,可以将各个页面共性的部分抽离出来,单独编写模板
    B、模板页是所有页面都要使用的,可以使用模板继承的方式来使各个页面都可以使用,只需修改模板页,所有继承的页面也会随之改变
    C、只使用页面的继承会抹杀掉各个页面独有的部分,使得所有的页面都是一个模样,这时需要使用block的方式为个性修改留下空间
    D、查看HTML页面,复制一个页面作为base基础模板
    E、查看分析网页共性和个性的部分,共性部分不发生改动,个性部分使用{% block %} {% endblock %}定义
    F、可以使用{% extends "模板名称.html" %}继承基础模板
    G、可以使用{% include "模板名称.html" %}导入整个页面,将需要的页面拉到当前页面的指定位置
    H、修改个性:直接在个性页面的部分使用block方法,个性部分会覆盖继承的原数据
(2)继承与加载
    A、定义一个模板页base,将网页共性的部分保留下来,在需要修改部分定义块标签block
    B、其他页面继承模板页,只需要使用块标签修改属于自己的部分就可以了
    C、块标签内部可以有默认值,共性的部分如果发生修改,只需要修改base页面
    D、定义块: {% block 块名 %}"默认值"{% endblock %}
    F、继承模板,可以修改块标签部分:{% extends "模板块名称" %}
    G、加载模板,直接拉取渲染页面:{% include  "html文件" %}
    H、模板继承可以使每个页面的特定元素(如页头、导航和页尾) 保持一致
(3)变量{{}}:可以接收视图函数传递过来的对象并调用方法
    A、{{变量.upper()}}:字符串值所有英文字母大写
    B、{{变量.索引}}:获取字符串对应索引的字符
    C、{{变量.split("数据")}}:按照给定数据分割
    D、{{变量.replace('数据1','数据2')}}:将变量中的数据1替换成数据2
(4)if标签:{% if 条件1 %}-{% elif 条件2 %}-{% else %}-{% endif %}
(5)for标签:{% for 变量 in 可迭代对象 %}-{% else %}-{% endfor %}
(6)loop变量:内置在for-loop循环中
    A、loop.index:返回循环对象从1开始的索引
    B、loop.index0:返回循环对象从0开始的索引
    C、loop.first:判断是否第一个
    D、loop.last:判断是否是最后一个
    E、loop.length:给出长度
(7)过滤器:将视图传递的数据,进行二次处理  {{ 变量|方法(upper、lower、safe) }}
    A、upper过滤,字母全部大写:{{ arg|upper }}
    B、lower过滤,字母全部小写:{{ arg|lower }}
    C、capitalize过滤,首字母大写:{{ arg|capitalize }}
    D、title过滤,标题形式:{{ arg|title }}
    E、replace过滤,替换数据:{{ arg|replace("A","d") }}
    F、round过滤,四舍五入:{{ arg|round|类型int }}
    G、safe过滤,安全展示:{{ arg|safe }}
    H、过滤器当中有个性的过滤器 safe取消了前端代码转义:{{ script|safe }}
        >> 转义: 模版认为视图传递的标签语言不安全,会将这部分内容进行转义为普通字符串
        >> 安全策略:最影响网站安全的手段有一种注入攻击
        >> 注入攻击:前端注入,数据库注入
        >> Flask本身携带反前端注入安全策略,使用safe过滤器可以解除安全策略
    C、过滤器在开发当中通常用于自定义
        >> 定义用于指定过滤规则的函数
        >> 全局-添加过滤规则到app中:app.add_template_filter(函数名,"规则名")
        >> 装饰器-添加过滤规则到app中(在自定义函数上):@app.template_filter('规则名')
        >> 前端使用:{{ 变量名|规则名 }}
(8)自动转义默认开启
    A、信任某个变量,且确定是安全的html,可以使用Markup类标记为安全的,或在模板中使用|safe过滤器
    B、from markupsafe import Markup
    C、Markup(f'<strong>Hello <blink>hacker</blink>!</strong>')
    D、Markup.escape('<blink>hacker</blink>')
    E、Markup('<em>Marked up</em> &amp;raquo; HTML').striptags()
"""
import os
import random

from flask import Flask, render_template
from flask import Markup
basic = "F:/MyProject"

app = Flask(__name__)


def ff(arg, b):
    return Markup(arg + b)

# 自定义过滤器-单参数
def myadd(number):
    number = str(number)
    if len(number)!=11:
        number = None
    elif type(eval(number))!=int:
        number = None
    else:
        number = number[:3]+"****"+number[-4:]
    return number
# 模板过滤器:自定义函数名,前端传递数据(过滤器名)
app.add_template_filter(myadd, "MyAdd")

# 自定义过滤器 - 多参数
def mymoney(num1, num2, num3):
    return num1 + num2 + num3
# 模板过滤器:自定义函数名,前端传递数据(过滤器名)
app.add_template_filter(mymoney, "MyMoney")

# 自定义过滤器规则(替换敏感词为**),注意在全局添加过滤filter
def filter_name(args):
    if len(args) == 0:
        obj = args.replace("傻逼", "**")
    else:
        username = args[0]
        gender = args[1]
        if gender == "男":
            obj = username[0] + "先生"
        elif gender == "女":
            obj = username[0] + "女士"
        else:
            obj = username
    return obj
# 添加过滤器,调用name函数,指定过滤器规则NAME
app.add_template_filter(filter_name, "SENSITIVE")

# 定义加密号码的过滤器(使用装饰器)
@app.template_filter('ENCRYPT')
def filter_number(obj):
    obj = str(obj)
    if len(obj) == 11:
        return f"{obj[:3]}****{obj[7:]}"
    else:
        return '号码有问题~'

# 定义一个模板页,通过include方法可以将这个页面引用加载到新页面中
@app.route('/template/include')
def include():
    # 加载指定目录下的templates目录中的html,使用render_template将数据返回
    return render_template("include.html")


# 定义一个模板页,通过extends方法可以对页面中私有部分进行修改
@app.route('/template/extends')
def extends():
    # 加载指定目录下的templates目录中的html,使用render_template将数据返回
    return render_template("extends.html")

@app.route("/")
def index():
    a = 123
    dct = {
        1: {"name": "TT", "long": 160, "颜值": 50},
        2: {"name": "KK", "long": 170, "颜值": 60},
        3: {"name": "GG", "long": 190, "颜值": 80}
    }
    html = "<h1>TT is sb</h1>"
    # 前端调用:{{ num | MyAdd }}
    # 前端调用:{{ num | MyMoney(20,10) }}
    return render_template("index1.html", num=a, user_dic=dct, htm=html, ff=ff)

# 可以接收视图函数传递过来的对象并调用方法将数据进行处理
@app.route('/template/label')
def label():
    init = 'init_Info'
    img = "资料/"+random.choice([file for file in os.listdir(f"{basic}/static/imgs/资料")])
    user = "哈哈"
    pswd = "xun961031"
    status = "管理员"
    lst = ["loop首位", "Java", "PHP", "Python", "JavaScript", "loop末尾位"]
    detail = "detail_Info"
    script = "<script>window.location.href = '#'</script>"
    words = "他是个大sb~"
    number = 18810629376
    books = [
        {"name": "《西游记》", "type": "必读", "author": "朋朋", "public": "延边出版社"},
        {"name": "《奥特曼战矮人》", "type": "选读", "author": "森森", "public": "新华"},
        {"name": "《卖书的葫芦》", "type": "必读", "author": "迅迅", "public": "西安"},
        {"name": "《天线宝宝》", "type": "选读", "author": "安安", "public": "清华大学"},
        {"name": "《桃花大战菊花》", "type": "必读", "author": "框框", "public": "中公"}
    ]
    # 数据以全部形式返回:return render_template("html文件",**locals())
    # locals():将局部函数内所有参数,按键=值的方式,将所有参数添加到一个字典中进行打包传递
    # **locals():是对局部变量整合的一个字典,传递时需要**打包
    return render_template("label.html", **locals())

@app.route('/args/<func>')
def args_demo(func):
    os.system(f'python {basic}//test//client.py {func}')
    data = f'执行{func}函数功能,已完成{func.split("_")[0]}请求~'
    return render_template('base1.html', **locals())

if __name__ == '__main__':
    # 模板过滤器:自定义函数名,前端传递数据(过滤器名)
    app.add_template_filter(myadd, "MyAdd")
    # 模板过滤器:自定义函数名,前端传递数据(过滤器名)
    app.add_template_filter(mymoney, "MyMoney")
    # 添加过滤器,调用name函数,指定过滤器规则NAME
    app.add_template_filter(filter_name, "SENSITIVE")
    def run(self):
        app.run(
            # host:主机地址
            host="localhost",
            # port:访问端口
            port=80,
            # debug:调试模式,测试环境True,生产环境Fasle
            debug=True,
            # use_reloader:自动重启
            use_reloader=True
        )
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值