lif*_*ter 11 frameworks cherrypy jinja2 python-2.7
这是我第一次深入研究python中的web开发.我唯一的另一个经验是PHP,我之前从未使用过框架,所以我发现这非常令人生畏和困惑.
我有兴趣学习CherryPy/Jinja2为我的NAS制作ZFS监视器.我已经阅读了关于CherryPy/Jinja2的文档的基础知识,但我发现样本是脱节的而且过于简单化,我真的不明白如何使这两个东西"优雅地聚集在一起".
我有一些问题:
有没有一个简单的教程显示你如何使CherryPy和Jinja2很好地协同工作?我要么发现过于简单的样本,比如CherryPy/Jinja2文档中的样本,要么是复杂的样本.(例如:https: //github.com/jovanbrakus/cherrypy-example).
是否有标准化或"预期"的方式为CherryPy创建Web应用程序?(例子:我的目录结构应该是什么样的?有没有办法声明静态的东西;它甚至是必要的吗?)
有没有人为此推荐文献或在线文档是最好的资源?
ljs*_*dev 30
恭喜选择Python,我相信你会像我一样学会爱它.
关于CherryPy,我不是专家,但几天前也和你在同一条船上,我同意这些教程的部分内容有点脱节.
为了集成Jinja2,就像在他们的doc页面中一样,HTML的片段应该被指定为模板文件,因此保存在路径/templates/index.html中.他们还使用了模板代码示例和控制器示例中不匹配的变量.
以下是使用CherryPy和Jinja2的简单hello世界的完整工作样本
/main.py:
import cherrypy
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates'))
class Root:
@cherrypy.expose
def index(self):
tmpl = env.get_template('index.html')
return tmpl.render(salutation='Hello', target='World')
cherrypy.config.update({'server.socket_host': '127.0.0.1',
'server.socket_port': 8080,
})
cherrypy.quickstart(Root())
Run Code Online (Sandbox Code Playgroud)
/templates/index.html:
<h1>{{ salutation }} {{ target }}</h1>
Run Code Online (Sandbox Code Playgroud)
然后在shell /命令提示符下,使用以下命令提供应用程序:
python main.py
Run Code Online (Sandbox Code Playgroud)
在您的浏览器中,您应该能够看到它 http://localhost:8080
这有助于您将Jinja2模板连接到您的CherryPy应用程序.CherryPy确实是一个轻量级且非常灵活的框架,您可以选择许多不同的方式来构建代码和文件结构.
saa*_*aaj 12
首先是关于项目的标准目录结构.没有,因为CherryPy没有强制要求,也没有告诉你使用什么数据层,表单验证或模板引擎.这完全取决于您和您的要求.当然,这是一个很大的灵活性,因为它会给初学者带来一些困惑.这是接近真实单词应用程序目录结构的样子.
. — Python virtual environment
??? website — cherryd to add this to sys.path, -P switch
??? application
? ??? controller.py — request routing, model use
? ??? model.py — data access, domain logic
? ??? view — template
? ? ??? layout
? ? ??? page
? ? ??? part
? ??? __init__.py — application bootstrap
??? public
? ??? resource — static
? ??? css
? ??? image
? ??? js
??? config.py — configuration, environments
??? serve.py — bootstrap call, cherryd to import this, -i switch
Run Code Online (Sandbox Code Playgroud)
然后站在虚拟环境的根目录中,您通常会执行以下操作以在开发环境中启动CherryPy.cherryd
是CherryPy建议运行应用程序的方法.
. bin/activate
cherryd -i serve -P website
Run Code Online (Sandbox Code Playgroud)
现在让我们看一下模板目录及其外观.
.
??? layout
? ??? main.html
??? page
? ??? index
? ? ??? index.html
? ??? news
? ? ??? list.html
? ? ??? show.html
? ??? user
? ? ??? profile.html
? ??? error.html
??? part
??? menu.html
Run Code Online (Sandbox Code Playgroud)
为了利用Jinja2的模板继承功能,这里有定义页面结构的布局,可以在特定页面中填充的插槽.您可能拥有网站布局和电子邮件通知布局.还有一个部件目录,可在不同页面使用的可重复使用的代码段.现在让我们看一下与上面结构相对应的代码.
我已经将以下内容作为runnable提供,它更容易导航文件,您可以运行和使用它.路径从.
第一部分的树开始.
网站/ config.py
# -*- coding: utf-8 -*-
import os
path = os.path.abspath(os.path.dirname(__file__))
config = {
'global' : {
'server.socket_host' : '127.0.0.1',
'server.socket_port' : 8080,
'server.thread_pool' : 8,
'engine.autoreload.on' : False,
'tools.trailing_slash.on' : False
},
'/resource' : {
'tools.staticdir.on' : True,
'tools.staticdir.dir' : os.path.join(path, 'public', 'resource')
}
}
Run Code Online (Sandbox Code Playgroud)
网站/ serve.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from application import bootstrap
bootstrap()
# debugging purpose, e.g. run with PyDev debugger
if __name__ == '__main__':
import cherrypy
cherrypy.engine.signals.subscribe()
cherrypy.engine.start()
cherrypy.engine.block()
Run Code Online (Sandbox Code Playgroud)
网站/应用/ __ init__.py
这里值得注意的部分是CherryPy工具,它有助于避免与渲染模板相关的样板.您只需dict
要从CherryPy页面处理程序返回一个包含模板数据的a.遵循约定优于配置原则,未提供模板名称的工具将使用classname/methodname.html
例如user/profile.html
.要覆盖您可以使用的默认模板@cherrypy.tools.template(name = 'other/name')
.另请注意,该工具会自动公开方法,因此您无需@cherrypy.expose
在顶部附加
# -*- coding: utf-8 -*-
import os
import types
import cherrypy
import jinja2
import config
class TemplateTool(cherrypy.Tool):
_engine = None
'''Jinja environment instance'''
def __init__(self):
viewLoader = jinja2.FileSystemLoader(os.path.join(config.path, 'application', 'view'))
self._engine = jinja2.Environment(loader = viewLoader)
cherrypy.Tool.__init__(self, 'before_handler', self.render)
def __call__(self, *args, **kwargs):
if args and isinstance(args[0], (types.FunctionType, types.MethodType)):
# @template
args[0].exposed = True
return cherrypy.Tool.__call__(self, **kwargs)(args[0])
else:
# @template()
def wrap(f):
f.exposed = True
return cherrypy.Tool.__call__(self, *args, **kwargs)(f)
return wrap
def render(self, name = None):
cherrypy.request.config['template'] = name
handler = cherrypy.serving.request.handler
def wrap(*args, **kwargs):
return self._render(handler, *args, **kwargs)
cherrypy.serving.request.handler = wrap
def _render(self, handler, *args, **kwargs):
template = cherrypy.request.config['template']
if not template:
parts = []
if hasattr(handler.callable, '__self__'):
parts.append(handler.callable.__self__.__class__.__name__.lower())
if hasattr(handler.callable, '__name__'):
parts.append(handler.callable.__name__.lower())
template = '/'.join(parts)
data = handler(*args, **kwargs) or {}
renderer = self._engine.get_template('page/{0}.html'.format(template))
return renderer.render(**data) if template and isinstance(data, dict) else data
def bootstrap():
cherrypy.tools.template = TemplateTool()
cherrypy.config.update(config.config)
import controller
cherrypy.config.update({'error_page.default': controller.errorPage})
cherrypy.tree.mount(controller.Index(), '/', config.config)
Run Code Online (Sandbox Code Playgroud)
网站/应用/ controller.py
正如您所看到的那样,使用工具页面处理程序看起来相当干净,并且与其他工具保持一致,例如json_out
.
# -*- coding: utf-8 -*-
import datetime
import cherrypy
class Index:
news = None
user = None
def __init__(self):
self.news = News()
self.user = User()
@cherrypy.tools.template
def index(self):
pass
@cherrypy.expose
def broken(self):
raise RuntimeError('Pretend something has broken')
class User:
@cherrypy.tools.template
def profile(self):
pass
class News:
_list = [
{'id': 0, 'date': datetime.datetime(2014, 11, 16), 'title': 'Bar', 'text': 'Lorem ipsum'},
{'id': 1, 'date': datetime.datetime(2014, 11, 17), 'title': 'Foo', 'text': 'Ipsum lorem'}
]
@cherrypy.tools.template
def list(self):
return {'list': self._list}
@cherrypy.tools.template
def show(self, id):
return {'item': self._list[int(id)]}
def errorPage(status, message, **kwargs):
return cherrypy.tools.template._engine.get_template('page/error.html').render()
Run Code Online (Sandbox Code Playgroud)
在这个演示应用程序中,我使用了blueprint css文件来演示静态资源处理的工作原理.把它放进去website/application/public/resource/css/blueprint.css
.剩下的就不那么有趣了,只是Jinja2模板的完整性.
网站/应用/视图/布局/ main.html中
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='content-type' content='text/html; charset=utf-8' />
<title>CherryPy Application Demo</title>
<link rel='stylesheet' media='screen' href='/resource/css/blueprint.css' />
</head>
<body>
<div class='container'>
<div class='header span-24'>
{% include 'part/menu.html' %}
</div>
<div class='span-24'>{% block content %}{% endblock %}</div>
</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
网站/应用/视图/页/指数/ index.html的
{% extends 'layout/main.html' %}
{% block content %}
<div class='span-18 last'>
<p>Root page</p>
</div>
{% endblock %}
Run Code Online (Sandbox Code Playgroud)
网站/应用/视图/页/新闻/ list.html
{% extends 'layout/main.html' %}
{% block content %}
<div class='span-20 last prepend-top'>
<h1>News</h1>
<ul>
{% for item in list %}
<li><a href='/news/show/{{ item.id }}'>{{ item.title }}</a> ({{ item.date }})</li>
{% endfor %}
</ul>
</div>
{% endblock %}
Run Code Online (Sandbox Code Playgroud)
网站/应用/视图/页/新闻/ show.html
{% extends 'layout/main.html' %}
{% block content %}
<div class='span-20 last prepend-top'>
<h2>{{ item.title }}</h2>
<div class='span-5 last'>{{ item.date }}</div>
<div class='span-19 last'>{{ item.text }}</div>
</div>
{% endblock %}
Run Code Online (Sandbox Code Playgroud)
网站/应用/视图/页/用户/ profile.html
{% extends 'layout/main.html' %}
{% block content %}
<div class='span-18'>
<table>
<tr><td>First name:</td><td>John</td></tr>
<tr><td>Last name:</td><td>Doe</td></tr>
<table>
</div>
{% endblock %}
Run Code Online (Sandbox Code Playgroud)
网站/应用/视图/页/的error.html
这是一个404页.
{% extends 'layout/main.html' %}
{% block content %}
<h1>Error has happened</h1>
{% endblock %}
Run Code Online (Sandbox Code Playgroud)
网站/应用/视图/零件/ menu.html
<div class='span-4 prepend-top'>
<h2><a href='/'>Website</a></h2>
</div>
<div class='span-20 prepend-top last'>
<ul>
<li><a href='/news/list'>News</a></li>
<li><a href='/user/profile'>Profile</a></li>
<li><a href='/broken'>Broken</a></li>
</ul>
</div>
Run Code Online (Sandbox Code Playgroud)
上面的代码与qooxdoo-website-skeleton的后端部分密切相关.对于这种应用程序的完整Debain部署,cherrypy-webapp-skeleton可能很有用.
归档时间: |
|
查看次数: |
8816 次 |
最近记录: |