Flask模板

        实际场景中的响应页面不会像我们做demo那样,返回一个很简单的HelloWorld。实际场景中,几千上万行的前端代码都有可能,这个时候把前端的代码放在试图函数中就显得很繁琐,并且很不好管理。Flask提供了相应页面的方案:构建模板。模板包含了前端的页面静态程序以及动态的变量,最终渲染成页面返回给用户。

        Flask使用了Jinja2模板引擎,用来渲染页面。模板搜索路径默认在项目根目录下templates文件夹下,例:

<!-- templates/user.html -->
<h1>Hello, {{ name }}!</h1>

一、渲染模板

        在上面的模板中出现了{{ name }}这样的代码,表明name是个变量,需要视图函数给出,然后由模板渲染,视图函数例:

@app.route('/user/<name>')
def user(name):
    return render_template('user.html', name=name)

        Flask提供了render_template()函数将模板集成到了应用中,第一个参数是文件名,随后的参数都是键值对,键表示模板中的变量,值表示函数给出变量对应的值。

模板除了识别简单变量,还可以识别复杂变量

<p>A value from a dictionary: {{ mydict['key'] }}.</p>
<p>A value from a list: {{ mylist[3] }}.</p>
<p>A value from a list, with a variable index: {{ mylist[myintvar] }}.</p>
<p>A value from an object's method: {{ myobj.somemethod() }}.</p>

变量的值可以通过过滤器修改,例首字母大写:

<!-- templates/user.html -->
<h1>Hello, {{ name|capitalize }}!</h1>

常用过滤器如下: 

Jinja2变量过滤器
过滤器名说明
safe渲染时不转义
capitalize只首字母大写,其它字母小写
lower全部小写
upper全部大写
title单词首字母大写
strim首尾去空格
striptags去掉所有的HTML标签

        safe过滤器比较特殊,jinja2默认会转移所有字符,包括前端代码,比如‘<h1>’会被渲染成‘&lt;’,但有时候前端页面需要显示前端代码,就可以用safe。不能在表单提交中使用safe,防止被攻击。

二、控制结构

        模板也有控制结构语句,条件判断、循环,甚至类似函数的宏以及引入和继承等。

条件判断:

{% if user %}
    Hello, {{ user }}!
{% else %}
    Hello, Stranger!
{% endif %}

循环:

<ul>
    {% for comment in comments %}
        <li>{{ comment }}</li>
    {% endfor %}
</ul>

宏:

{% macro render_comment(comment) %}
    <li>{{ comment }}</li>
{% endmacro %}
<ul>
    {% for comment in comments %}
    {{ render_comment(comment) }}
    {% endfor %}
</ul>

为了重复使用宏,可以单独保存在一个文件,在需要的模板中导入:

{% import 'macros.html' as macros %}
<ul>
    {% for comment in comments %}
    {{ macros.render_comment(comment) }}
    {% endfor %}
</ul>

引入重复使用模板代码:

{% include 'common.html' %}

继承:

<!-- templates/base.html -->
<html>
<head>
    {% block head %}
    <title>{% block title %}{% endblock %} - My Application</title>
    {% endblock %}
</head>
<body>
    {% block body %}
    {% endblock %}
</body>
</html>

<!-- templates/other.html -->
{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
 {{ super() }}
 <style>
 </style>
{% endblock %}
{% block body %}
<h1>Hello, World!</h1>
{% endblock %}

继承的基模板使用区块定义,在继承模板中可以对这些块进行重写,如果需要使用基模板的相同内容可以使用super()。

三、模板中的链接

        在模板中不能把链接写死,如果开发的路由变更,模板的链接将难以维护,为了避免这个问题,Flask提供了url_for()辅助函数,用来动态生成URL。

url_for()最简单的方式使用视图函数名作为参数,例:

url_for('index)  # / 相对路径
url_for('index', _externl=True)  # http://localhost:5000/ 绝对路径
url_for('user', name='john', _external=True)  # http://localhost:5000/user/john  动态路由
url_for('user', name='john', page=2, version=1)  # /user/john?page=2&version=1  动态路由+查询参数

四、静态文件

        静态文件默认保存在根目录的static文件夹下,可以建立子文件夹。在模板中使用时如下,定义一个收藏夹图标:

{% block head %}
{{ supper() }}
<link rel="short icon" href="{{ url_for('static', filename='favicon.ico') }}", type="image/x-icon">
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}", type="image/x-icon">
{% endblock %}

注:本章写的比较笼统,主要因为有个认识就可以,学一遍就好了。因为实际应用不会使用模板,牵涉到传输、带宽、项目规划的问题。如果是开发软件的话,会使用前后端分离的方式。如果开发数据接口或者算法接口的话并不会用到这些内容,所以说如果不是必须,了解一下就好。我是后者,仅用来写接口。

参考资料:《Flask Web开发(第二版)》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NAND Flash是一种非易失性存储器件,由于其高速、低功耗、低成本等特点,已经成为现代电子设备中最常用的存储媒介。在使用NAND Flash进行数据存储时,需要使用Flash Translation Layer(FTL)来管理其物理块(PBA)和逻辑块(LBA)之间的映射关系。以下是一个简单的NAND Flash FTL模板,以供参考: ```python class FTL: def __init__(self, n_blocks, block_size, page_size): self.n_blocks = n_blocks # 总物理块数 self.block_size = block_size # 每个物理块的大小 self.page_size = page_size # 每个物理块中的页面大小 self.lba_to_pba = {} # LBA到PBA的映射表 self.free_blocks = set(range(n_blocks)) # 空闲物理块集合 def write(self, lba, data): # 检查是否需要新分配物理块 if lba not in self.lba_to_pba: if not self.free_blocks: raise Exception('Out of space!') pba = self.free_blocks.pop() self.lba_to_pba[lba] = pba pba = self.lba_to_pba[lba] # 写数据到物理块中 # ... def read(self, lba): if lba not in self.lba_to_pba: raise Exception('Block not found!') pba = self.lba_to_pba[lba] # 从物理块中读取数据 # ... def erase(self, lba): if lba not in self.lba_to_pba: raise Exception('Block not found!') pba = self.lba_to_pba[lba] # 擦除物理块 # ... self.free_blocks.add(pba) del self.lba_to_pba[lba] ``` 在这个模板中,我们使用一个字典`lba_to_pba`来记录LBA和PBA之间的映射关系。在写入数据时,如果该LBA没有对应的PBA,则需要从空闲物理块中选择一个新的物理块,并将其分配给该LBA。在读取数据时,我们可以从`lba_to_pba`中查找该LBA对应的PBA,并从该PBA中读取数据。在擦除数据时,我们需要擦除该LBA对应的PBA,并将该PBA重新加入到空闲物理块集合中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值