1.初识Jinja2、搭配Bootstrap

本文介绍了如何利用Jinja2模板引擎和Flask-Bootstrap库在Python web开发中构建动态网页。内容包括Jinja2的渲染原理、变量和控制结构的使用,以及Flask-Bootstrap的安装、初始化和在模板中的应用。通过模板继承和宏实现页面的复用,同时讲解了错误页的定制、链接生成和静态文件的管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

·

Jinja2是啥

为了把业务逻辑和表现逻辑分离,将表现逻辑移到模板中是不错的选择;模板是一个包含响应文本的文件,里面用占位变量来表示动态部分,当有上下文时再用真实的值取代之并返回最终得到的响应字符串,这个过程就叫渲染,Jinja2是渲染模板的模板引擎

如何渲染

模板的位置默认是在程序文件夹中的templates子文件夹中寻找,渲染模板有个render_template('模板文件名', [键值对参数])函数,返回传入了参数的响应字符串,html文件部分:

<!--程序目录/template/user.html-->
<h1>Hello, your name is : {{ name }}~</h1>
--------------------------------------------
<!--程序目录/template/index.html-->
<h1>Hello, im index~</h1>

程序部分:

@app.route('/')
def index():
    return render_template('index.html')

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

效果是和之前是一样的,只是这次是通过渲染模板

模板文件夹的位置可以更改:在实例化时传入template_folder参数,即Flask(name,template_folder=”存放模板文件夹名称”)

变量

在模板中用{{ }}占位符来表示一个变量,里面放变量名,Jinja2能识别所有类型的变量,list、dict、tuple、对象都可,这里要提一句过滤器,它可以根据需求修改变量,用竖线分隔变量名后加在后面,如下:
hi, {{ name|upper }}
upper过滤器把变量name的值都转换成了大写,下面是一些常用过滤器:

过滤器名说 明
safe渲染值时不转义
capitalize把值的首字母转换成大写,其他字母转换成小写
lower把值转换成小写形式
upper把值转换成大写形式
title把值中的每个单词的首字母都转换成大写
trim把值的首尾空格去掉
striptags渲染之前把值中所有的HTML标签都删掉

控制结构

顾名思义,可以在模板中用条件控制语句,如if、for,具体见下例:

----------------if-------------------

{% if user %}
    Hello, {{ user }}!
{% else %}
    Hello, Stranger!
{% endif %}
---------------for--------------------
<ul>
    {% for comment in comments %}
        <li>{{ comment }}</li>
    {% endfor %}
</ul>

Jinja2还支持,简化重复操作,可以把宏保存在单独的文件中,需要时导入

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

重复使用模板的常用两种方法:
include:把文件包含进来,语句{% include 'common.html' %}
extends:模板继承,其中block元素可以在衍生模板中修改,语句{% extends "base.html" %}

下面为base模板和继承自base模板的衍生模板例子:

-----------------------base.html---------------------------
<html>
<head>
    {% block head %}
    <title>{% block title %}{% endblock %}万事屋</title>
    {% endblock %}
</head>
<body>
    {% block body %}
    {% endblock %}
</body>
</html>
------------------------index.html--------------------------
{% extends "base.html" %}
{% block title %}首屋{% endblock %}
{% block head %}
    {{ super() }}
    <style>
    </style>
{% endblock %}
{% block body %}
<h1>Hello man</h1>
{% endblock %}

要说一下super(),它的作用是获取原来的内容,如果要在已经有内容的block中添加新内容,需要先用它

Flask-Bootstrap的使用

Bootstrap是客户端框架,不会直接涉及服务器,服务器只需提供引用了Bootstrap的代码响应,并在前端代码中实例化所需组件,我们在模板中执行这些操作

安装和初始化

除了直接修改模板来集成Bootstrap,还可以用Flask拓展中的Flask-Bootstrap,安装只需一行代码的功夫:
pip install flask-bootstrap

初始化也是和之前一样,在创建程序实例时进行:

from flask_bootstrap import Bootstrap 
#...
bootstrap = Bootstrap(app)

开始用

下面是继承了Bootstrap的base模板的user页,可理解为base模板中画好了骨架,在衍生模板中填肉,其中title、navbar、content块中的内容都是填的:

{% extends "bootstrap/base.html" %}

{% block title %}欢迎屋{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/">万事屋</a>
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li><a href="/">HOME</a></li>
            </ul>
        </div>
    </div>
</div>
{% endblock %}

{% block content %}
<div class="container">
    <div class="page-header">
        <h1>Hello, {{ name | upper}}!</h1>
    </div>
</div>
{% endblock %}

访问user页,一下子就美观不少有木有:
这里写图片描述

base模板中定义的块:

块名说明
doc整个HTML文档
html_attribs<html>标签的属性
html<html>标签中的内容
head<head>标签中的内容
title<title>标签中的内容
metas一组<meta>标签
styles层叠样式表定义
body_attribs<body>标签中的内容
navbar用户定义的导航条
content用户定义的页面内容
scripts文档底部的JavaScript声明

为了以后的页面继承起来更方便,避免每次继承Bootstrap的base模板时做重复修改,我们可以自己定义一个base模板:

{% extends "bootstrap/base.html" %}

{% block title %}万事屋{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle"
             data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/">万事屋</a>
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li><a href="/">Home</a></li>
                <li><a href="/user/Master">欢迎屋</a></li>
            </ul>
        </div>
    </div>
</div>
{% endblock %}

{% block content %}
<div class="container">
    {% block page_content %}{% endblock %}
</div>
{% endblock %}    

错误页

当访问无效或发生异常时会有错误页(通常很简陋),为了使其和其他页面一致,我们通过继承模板来美化它
后端部分,添加两个路由,注意返回值的第二个是状态码

@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404

@app.errorhandler(500)
def internal_server_error(e):
    return render_template('500.html'), 500

前端添加相应的页面,以404为例,新建404.html并继承 自己的 base模板,即:

{% extends "base.html" %}

{% block title %}空屋{% endblock %}


{% block page_content %}
<h1>空荡荡</h1>
{% endblock %}

链接

当写导航条标签的URL时,手写有时会很困难(如有动态部分),Flask也想到这点,所以有了url_for()函数,它返回视图函数对应的URL,以视图函数名作为参数,如果需要返回绝对地址则传入参数_external=True

生成连接程序内不同路由的链接时用相对地址足矣,若要生成在浏览器之外使用的链接则必须用绝对地址

url_for()生成动态地址时,可以将动态部分作为关键字参数传入,而且不仅限于动态路由中的参数,可以是任何额外参数,如url_for('index', page=66)的返回结果就是/?page=66

PS:URL中用?分隔URL和传输数据(如参数),参数之间用&相连,若遇到空格则转为+,若是中文就用BASE64加密后得到16进制表示的ASCII码,像这样%XX

静态文件

之前在用app.url_map检查URL映射时发现有个static路由,该路由是对静态文件的引用,即/static/<filename>,举个例子就很容易明白,调用url_for('static', filename='css/styles.css', _external=True),得到的就是styles.css文件的绝对地址,服务器收到这个URL后会生成一个包含该文件内容的响应

正常情况下,静态文件放在程序根目录的static子目录中;试试在该目录中放一个图片,以该图作为页面图标:

{% block head %}
{{ super() }}  
<link rel="shortcut icon" href="{{ url_for('static', filename='laugh.jpg') }}"
    type="image/x-icon">
<link rel="icon" href="{{ url_for('static', filename='laugh.jpg') }}"
    type="image/x-icon">
{% endblock %}

运行如图:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值