Python Pyramid 包结构
Cookiecutter工具会自动在同名的父项目文件夹中创建一个包文件夹。包文件夹包括以下文件和子文件夹。
init.py
一个文件夹需要 __init__.py 文件才能被视为Python包。这个 testproj 包也有这个文件,它基本上声明了Pyramid WSGI应用程序项目,供development.ini使用作为入口点。
应用程序对象由 main() 函数返回。它通过在运行cookiecutter时包含所选择的模板库,包括 routes 模块,以及通过扫描现有包将视图添加到配置程序来配置应用程序注册表。以下Python代码是作为 __init__.py 文件的自动生成的。
from pyramid.config import Configurator
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
with Configurator(settings=settings) as config:
config.include('pyramid_jinja2')
config.include('.routes')
config.include('.models')
config.scan()
return config.make_wsgi_app()
routes.py
Cookiecutter工具会自动生成一个Python脚本,其中包含一个名为includeme()的函数。它会添加一个静态路由和一个指向’/’ URL模式的主页路由。
def includeme(config):
config.add_static_view('static', 'static', cache_max_age=3600)
config.add_route('home', '/')
这些路由是通过应用程序配置中的 main() 函数在 __init__.py 文件中解释上面所述而添加的。
视图包
项目包(在我们的例子中是 testproj 包)包含这个视图子包 – 一个包含一个空的 __init__.py 文件的文件夹,一个名为 default.py 的 Python 模块,其中定义了一个名为 my_view() 的视图函数。它将项目的名称作为上下文发送到一个预先构建的模板 mytemplate.jinja2 。
from pyramid.view import view_config
from pyramid.response import Response
from sqlalchemy.exc import SQLAlchemyError
from .. import models
@view_config(route_name='home', renderer='testproj:templates/mytemplate.jinja2')
def my_view(request):
try:
query = request.dbsession.query(models.MyModel)
one = query.filter(models.MyModel.name == 'one').one()
except SQLAlchemyError:
return Response(db_err_msg, content_type='text/plain', status=500)
return {'one': one, 'project': 'testproj'}
db_err_msg = """\
Pyramid is having a problem using your SQL database.
....
"""
default.py脚本还导入了models子包中的mymodel定义。该views包还在notfound.py文件中定义了一个notfound视图。
from pyramid.view import notfound_view_config
@notfound_view_config(renderer='testproj:templates/404.jinja2')
def notfound_view(request):
request.response.status = 404
return {}
静态文件夹
这个文件夹位于testproj包文件夹下,包含用于首页展示的Pyramid徽标文件和theme.CSS。
模板文件夹
我们知道网页模板需要存放在模板文件夹中。这个子文件夹包含了jinja2模板。这里有一个名为 layout.jinja2 的基础模板,它被 mytemplate.jinja2 继承,通过 my_view() 视图函数进行渲染。
{% extends "layout.jinja2" %}
{% block content %}
<div class="content">
<h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter project</span></h1>
<p class="lead">Welcome to <span class="font-normal">{{project}}</span>, a Pyramid application generated by<br><span class="font-normal">Cookiecutter</span>.</p>
</div>
{% endblock content %}
模型包
该包位于 tesptproj 包文件夹下的子包,其中包含名为 mymodel.py 的SQLAlchemy模型定义,该模型命名为 MyModel 。
from sqlalchemy import (
Column,
Index,
Integer,
Text,
)
from .meta import Base
class MyModel(Base):
__tablename__ = 'models'
id = Column(Integer, primary_key=True)
name = Column(Text)
value = Column(Integer)
Index('my_index', MyModel.name, unique=True, mysql_length=255)
meta.py 在SQLAlchemy中声明了一个Declarative Base类的对象。
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.schema import MetaData
NAMING_CONVENTION = {
"ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_%(constraint_name)s",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s"
}
metadata = MetaData(naming_convention=NAMING_CONVENTION)
Base = declarative_base(metadata=metadata)