使用 Pyramid 在视图和应用程序之间共享对象

Sharing objects between view and application with Pyramid

我正在尝试使用 Pyramid 为数据分析管道创建 Web 界面。我正在使用变形和漏勺来制作表格。我一直在改编这个例子:

http://pyramid-tutorials.readthedocs.org/en/latest/humans/security/step02/

大部分工作在提交表单后就完成了,但有几个通用步骤只需要 运行 一次。我可以在服务器启动时将一些东西加载到内存中,以便可以从视图中访问它们吗?

您可以在应用程序的主文件中(或者可能在其他地方)定义一些模块级变量,然后根据您的要求导入它们来使用它们。

我使用此方法从环境变量创建 SQLAlchemy 的数据库连接字符串等设置。

默认情况下,一个模块只会在 Python 中被解析一次,因此您的模块级代码只会 运行 一次。

更新 1

让我们假设金字塔项目的目录结构如下所示:

.
├── __init__.py
├── models
│   ├── __init__.py
│   ├── meta
│   │   ├── base.py
│   │   ├── __init__.py
│   │   ├── orm.py
│   │   ├── schema.py
│   │   ├── types.py
│   ├── users.py
├── security.py
├── settings
│   ├── database.py
│   ├── email.py
│   ├── __init__.py
│   ├── redis.py
│   ├── security.py
├── static
│   ├── css
│   │   └── main.css
│   └── js
│       ├── app.js
│       ├── app-services.js
│       ├── controllers
│       │   └── excel_preview.js
├── templates
│   ├── auth
│   │   └── login.html
│   ├── base.html
│   ├── home.html
├── views
│   ├── auth.py
│   ├── home.py
│   ├── __init__.py

假设我们在 settings/redis.py 中有以下代码:

import os
import redis


def get_redis_client():
    # Read settings from environment variables
    redis_db_name = os.environ.get('REDIS_NAME')
    redis_host = os.environ.get('REDIS_HOST')
    redis_port = os.environ['REDIS_PORT']

    # create a redis connection
    redis_client = redis.StrictRedis(
        host=redis_host,
        port=redis_port,
        db=redis_db_name,
    )

    # return newly created redis connection
    return redis_client


redis_client = get_redis_client()

SOME_SETTING_STORED_IN_REDIS = redis_client.get('some_setting_stored_in_redis')

您可以从任何地方使用这个 SOME_SETTING_STORED_IN_REDIS 变量。如果您的应用名称是 example_app 那么在 example_app/views/home.py 中您可以这样使用它:

from pyramid.view import view_config

from example_app.settings.redis import SOME_SETTING_STORED_IN_REDIS


def includeme(config):
    config.add_route('home', '/')


@view_config(
    route_name='home',
    renderer='home.html',
    permission='authenticated'
)
def home_view(request):

    return {
        "some_setting": SOME_SETTING_STORED_IN_REDIS,
    }

我认为您正在尝试实现类似的目标。

如果 "things which only need to run once" 你的意思是像数据库连接,一些配置数据等 - 换句话说,在流程的生命周期中永远不会改变的东西然后将它们定义为全局变量并在整个过程中重复使用申请没问题。示例:

APP_TITLE = 'Data Analysis Pipeline using Pyramid'

@view_config(...)
def home_view(request):
    return "Welcome to %s" % APP_TITLE

如果您正在考虑存储一些 全局状态 并在视图中重复使用它,那么这不是一个好主意。示例(不好,不要这样做):

subscription_step = 1

@view_config(...)
def next_subscription_step(request):
    global subscription_step
    subscription_step += 1 
    return HTTPFound('/subscription/step_%s' % subscription_step)

上面的代码可能在本地对你有用,但是一旦有多个用户访问应用程序,或者如果网络服务器生成另一个工作进程,或者如果网络服务器重新启动,或者一百万个其他原因。