如何在Pyramid中获取add_static_view()的文件路径

时间:2012-02-15 07:52:32

标签: python pyramid

当我像这样添加static view时:

cfg = config.Configurator(...)
cfg.add_static_view(name='static', path='MyPgk:static')

# And I want to add a view for 'favicon.ico'.
cfg.add_route(name='favicon', pattern='/favicon.ico')
cfg.add_view(route_name='favicon', view='MyPgk.views.mymodule.favicon_view')

如果在网页中未定义,我试图添加浏览器调用的/favicon.ico恼人的默认路径favicon.ico。我想在http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/files.html使用示例并将其修改为:

def favicon_view(request, cache=dict()):
    if (not cache):
        _path_to_MyPkg_static = __WHAT_GOES_HERE__
        _icon = open(os.path.join(_path_to_MyPkg_static, 'favicon.ico')).read()
        cache['response'] = Response(content_type='image/x-icon', body=_icon)
    return cache['response']

因为,我无法真正定义示例中提出的_here,如何使其依赖request来获取运行时的实际完整路径?或者我真的需要处理:

_here = os.path.dirname(__file__)
_path_to_MyPkg_static = os.path.join(os.path.dirname(_here), 'static')

当我决定重构并将视图放在另一个pkg或子包中时,或者在哪里时要小心?

等同于request.static_path()的东西,而不是获取url path,实际获得目录路径:

request.static_file_path('static') - > /path/to/site-packages/MyPkg/static

谢谢,

1 个答案:

答案 0 :(得分:3)

您可以使用pkg_resources模块创建相对于Python模块的路径(因此,独立于检索它们的模块)。例如:

import pkg_resources
print pkg_resources.resource_filename('os.path', 'static/favicon.ico')
# 'C:\\Python27\\lib\\static\\favicon.ico'

只需将os.path替换为静态文件的父模块。

编辑:如果您需要记住映射到'static'的{​​{1}}路由,那么最简单的方法是首先将其保存在某些字典中:

'MyPkg:static'

然后只需检索路径:

STATIC_ROUTES = {'static': 'MyPkg:static'}
for name, path in STATIC_ROUTES.iteritems():
    cfg.add_static_view(name=name, path=path)

如果这是不可能的(例如,您无法访问static_path = STATIC_ROUTES['static'] package, relative_path = static_path.split(':') icon_path = pkg_resources.resource_filename( package, os.path.join(relative_path, 'favicon.ico')) 对象),可以检索此路径,这非常痛苦。这是一个使用未记录的调用的示例函数(因此可能会在将来的Pyramid版本中更改)并忽略一些其他设置(如cfg配置变量):

route_prefix

在你的情况下,它应该像这样工作:

def get_static_path(request, name):
    from pyramid.config.views import StaticURLInfo
    registrations = StaticURLInfo()._get_registrations(request.registry)
    if not name.endswith('/'):
        name = name + '/'
    route_name = '__%s' % name
    for _url, spec, reg_route_name in registrations:
        print ':', reg_route_name
        if reg_route_name == route_name:
            return spec