- Python Pyramid 教程
- Python Pyramid - 首页
- Python Pyramid - 概述
- Pyramid - 环境搭建
- Python Pyramid - Hello World
- Pyramid - 应用配置
- Python Pyramid - URL 路由
- Python Pyramid - 视图配置
- Python Pyramid - 路由前缀
- Python Pyramid - 模板
- Pyramid - HTML 表单模板
- Python Pyramid - 静态资源
- Python Pyramid - 请求对象
- Python Pyramid - 响应对象
- Python Pyramid - 会话
- Python Pyramid - 事件
- Python Pyramid - 消息闪现
- Pyramid - 使用 SQLAlchemy
- Python Pyramid - Cookiecutter
- Python Pyramid - 创建项目
- Python Pyramid - 项目结构
- Python Pyramid - 包结构
- 手动创建项目
- 命令行 Pyramid
- Python Pyramid - 测试
- Python Pyramid - 日志记录
- Python Pyramid - 安全
- Python Pyramid - 部署
- Python Pyramid 有用资源
- Python Pyramid - 快速指南
- Python Pyramid - 有用资源
- Python Pyramid - 讨论
Python Pyramid - 模板
默认情况下,视图函数响应的 content-type 为纯文本。为了渲染 HTML,响应正文的文本可能包含 HTML 标签,如下例所示:
示例
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
def hello_world(request):
return Response('<h1 style="text-align:center;">Hello World!</h1>')
if __name__ == '__main__':
with Configurator() as config:
config.add_route('hello', '/')
config.add_view(hello_world, route_name='hello')
app = config.make_wsgi_app()
server = make_server('0.0.0.0', 6543, app)
server.serve_forever()
输出
启动服务器(运行上述代码)后,访问https://:6543/,浏览器将呈现以下输出:
然而,这种渲染 HTML 的方法,尤其是在可能包含某些变量数据的情况下,极其繁琐。为此,Web 框架使用模板库。模板库将变量数据与其他静态 HTML 代码合并,以动态生成和渲染网页。
模板绑定
Pyramid 通过绑定到流行的模板库(如 jinja2、Mako 和 Chameleon)来提供模板支持。
| 模板语言 | Pyramid 绑定 | 默认扩展名 |
|---|---|---|
| Chameleon | pyramid_chameleon | .pt, .txt |
| Jinja2 | pyramid_jinja2 | .jinja2 |
| Mako | pyramid_mako | .mak, .mako |
首先,我们需要安装使用所需模板库的相应 Python 库。例如,要使用 jinja2 模板,请使用 PIP 安装程序安装pyramid_jinja2。
pip3 install pyramid_jinja2
然后我们需要将其包含在应用程序配置中。
config.include('pyramid_jinja2')
pyramid.renderers 模块定义了 render_to_response() 函数。它与以下参数一起使用:
render_to_response(renderer_name, value, request)
renderer_name 是模板网页,通常保存在应用程序目录的 templates 子文件夹中,value 参数是一个作为上下文传递给模板的字典,以及从 WSGI 环境获得的请求对象。
将以下 HTML 脚本另存为 templates 文件夹中的hello.jinja2。
<html>
<body>
<h1>Hello, {{ name }}!</h1>
</body>
</html>
Jinja2 模板库
这里,“name”是 jinja2 模板变量。jinja2 模板语言使用以下语法在 HTML 脚本中插入变量和编程结构:
表达式
{{ ... }} 用于将表达式打印到模板输出。
{% ... %} 用于语句。
{# ... #} 用于模板输出中不包含的注释。
条件语句
{% if expr %}
{% else %}
{% endif %}
循环
{% for var in iterable %}
{% endfor %}
在 hello.jinja2 {{ name }} 中,'name' 上下文变量的值在视图响应中动态呈现。
渲染模板
hello_world() 视图函数通过调用render_to_response() 函数直接渲染此模板。它还向模板发送上下文值。
from pyramid.renderers import render_to_response
def hello_world(request):
return render_to_response('templates/hello.jinja2',{'name':'Tutorialspoint'},
request=request)
示例
像往常一样,此视图添加到指向 / URL 的 hello 路由。完整的应用程序代码如下:
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.renderers import render_to_response
def hello_world(request):
return render_to_response('templates/hello.jinja2', {'name':'Tutorialspoint'}, request=request)
if __name__ == '__main__':
with Configurator() as config:
config.add_route('hello', '/')
config.include('pyramid_jinja2')
config.add_view(hello_world, route_name='hello')
app = config.make_wsgi_app()
server = make_server('0.0.0.0', 6543, app)
server.serve_forever()
输出
运行服务器并访问https://:6543/。浏览器显示以下结果:
每个视图都必须返回一个响应对象。render_to_response() 函数是一个快捷函数,实际上返回一个响应对象。这允许上面的hello_world 视图直接返回其对render_to_response() 的调用的结果。
另一方面,pyramid.renderers.render() 函数将模板渲染为字符串。我们可以直接生成响应对象,并使用该字符串作为响应的主体。
让我们更改hello_world() 视图函数如下:
from pyramid.renderers import render
def hello_world(request):
retval = render('templates/hello.jinja2',
{'name':'Tutorialspoint'}, request=request)
return Response(retval)
其余代码相同,浏览器也显示与上述相同的输出。
通过配置进行渲染
如前所述,Pyramid 的视图可调用返回的 HTTP 响应的 content_type 为 text/plain。但是,如果@view_config 装饰器的 renderer 参数被赋值为这些值中的任何一个,则可以将其更改为字符串、JSON 或 JSONP。因此,Pyramid 具有以下内置渲染器:
JSON
字符串
JSONP
示例
在以下示例中,hello_world() 视图函数配置为渲染 JSON 响应。
from pyramid.view import view_config
@view_config(route_name='hello',renderer='json')
def hello_world(request):
return {'content':'Hello World!'}
输出
将渲染器类型设置为 JSON 还会将 HTTP 响应的content_type 标头设置为application/json。浏览器将显示如下所示的 JSON 响应:
@view_config() 装饰器的 renderer 参数可以设置为模板网页(必须存在于 templates 文件夹中)。前提条件是必须安装模板库的相应 Python 绑定,并且应用程序配置必须包含该绑定。
我们已经安装了 python_jinja2 包,因此我们可以使用 jinja2 模板由 hello_world() 视图函数呈现,该函数由带有 renderer 参数的 @view_config() 装饰。
hello.jinja2 模板 HTML 代码如下:
<html>
<body>
<h1>Hello, {{ name }}!</h1>
</body>
</html>
装饰的 hello_world() 函数编写如下:
from pyramid.view import view_config
@view_config(route_name='hello', renderer='templates/hello.jinja2')
def hello_world(request):
return {'name':'Pyramid!'}
示例
在这种情况下,视图函数返回一个字典对象。它作为上下文数据提供给模板,可以使用模板语言语法元素将其插入到 HTML 文本中。
渲染 jinja2 模板的完整代码如下:
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.view import view_config
@view_config(route_name='hello', renderer='templates/hello.jinja2')
def hello_world(request):
return {'name':'Pyramid!'}
if __name__ == '__main__':
with Configurator() as config:
config.include('pyramid_jinja2')
config.add_route('hello', '/')
config.scan()
app = config.make_wsgi_app()
server = make_server('0.0.0.0', 6543, app)
server.serve_forever()
输出
由视图函数提供的变量数据的模板网页如下所示:
添加/更改渲染器
模板只不过是散布着模板语言语法的网页。即使 Pyramid 使用 jinja2 模板的默认扩展名“.jinja2”,但惯例是使用网页的“.html”扩展名。
我们可以更改应用程序配置,以允许使用“.html”扩展名以及“.jinja2”。这是通过add_jinja2_renderer 完成的。
config.add_jinja2_renderer(".html")
hello.jinja2 模板现在重命名为 hello.html。为了能够使用此模板,让我们将视图函数定义更改为以下代码:
from pyramid.view import view_config
@view_config(route_name='hello', renderer='templates/hello.html')
def hello_world(request):
return {'name':'Pyramid!'}
同时,我们通过添加“.html”渲染器来修改 Configurator 对象的属性。
if __name__ == '__main__':
with Configurator() as config:
config.include('pyramid_jinja2')
config.add_jinja2_renderer(".html")
config.add_route(hello, '/')
config.scan()
app = config.make_wsgi_app()
server = make_server('0.0.0.0', 6543, app)
server.serve_forever()
来自 matchdict 的模板上下文
如前所述,如果路由配置中的 URL 模式包含一个或多个占位符参数,则来自请求 URL 的值将与请求一起作为matchdict 对象传递,该对象又可以作为上下文数据传递给要呈现的模板。
对于我们的下一个示例,hello.html(jinja2 模板)保持不变。
<html>
<body>
<h1>Hello, {{ name }}!</h1>
</body>
</html>
我们知道上下文变量“name”的值由视图函数传递。但是,与其传递硬编码值(如在前面的示例中),不如从matchict 对象中获取其值。此对象由 URL 字符串中的路径参数填充。
from pyramid.view import view_config
@view_config(route_name='index', renderer='templates/hello.html')
def index(request):
return {'name':request.matchdict['name']}
示例
修改后的应用程序代码如下:
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.view import view_config
@view_config(route_name='index', renderer='templates/hello.html')
def index(request):
return {'name':request.matchdict['name']}
if __name__ == '__main__':
with Configurator() as config:
config.include('pyramid_jinja2')
config.add_jinja2_renderer(".html")
config.add_route('index', '/{name}')
config.scan()
app = config.make_wsgi_app()
server = make_server('0.0.0.0', 6543, app)
server.serve_forever()
输出
启动服务器,打开浏览器并输入 URL https://:6543/Tutorialspoint。尾随字符串成为matchdict 中“name”键的值。它被 jinja2 模板利用,并呈现以下输出。
模板中的条件语句和循环
jinja2 模板语言允许在 HTML 脚本中包含条件语句和循环结构。这些编程元素的 jinja2 语法如下:
条件语句
{% if expr %}
HTML
{% else %}
HTML
{% endif %}
循环
{% for var in iterable %}
HTML
{% endfor %}
可以看出,jinja2 语法与 Python 的 if 和 for 语句非常相似。不同的是,jinja2 不使用缩进来标记块。相反,对于每个 if,都必须有一个 endif 语句。类似地,对于每个 for 语句,都必须有一个 endfor 语句。
示例
以下示例演示了模板条件语句和循环语句的使用。首先,Pyramid 代码使用 students 作为字典对象的列表,每个字典都具有学生的 id、姓名和百分比。此列表对象作为上下文传递给 marklist.html 模板
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.view import view_config
students = [
{"id": 1, "name": "Ravi", "percent": 75},
{"id": 2, "name": "Mona", "percent": 80},
{"id": 3, "name": "Mathews", "percent": 45},
]
@view_config(route_name='index', renderer='templates/marklist.html')
def index(request):
return {'students':students}
if __name__ == '__main__':
with Configurator() as config:
config.include('pyramid_jinja2')
config.add_jinja2_renderer(".html")
config.add_route('index', '/')
config.scan()
app = config.make_wsgi_app()
server = make_server('0.0.0.0', 6543, app)
server.serve_forever()
将此程序保存为 marklist.py。现在,以下 HTML 脚本必须保存为 marklist.html。它遍历从视图函数接收到的 students 列表对象,并以 HTML 表格的形式呈现学生数据。第四列使用 jinja2 if 语法显示及格/不及格结果。
<html>
<body>
<table border=1>
<thead>
<tr>
<th>Student ID</th> <th>Student Name</th>
<th>percentage</th>
<th>Result</th>
</tr>
</thead>
<tbody>
{% for Student in students %}
<tr>
<td>{{ Student.id }}</td>
<td>{{ Student.name }</td>
<td>{{ Student.percent }}</td>
<td>
{% if Student.percent>=50 %}
Pass
{% else %}
Fail
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
输出
运行marklist.py 代码。https://:6543/链接呈现以下表格结果: