问题
When I am adding a static view
like this:
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')
I am trying to add that favicon.ico annoying default path of /favicon.ico
called by the browser if it's undefined in the webpage. I would like to use the example at http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/files.html and modify it to have:
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']
Since, I can't really define the _here
proposed in the example, how can I make it dependent to request
to get the actual full path at runtime? Or do I really have to deal with:
_here = os.path.dirname(__file__)
_path_to_MyPkg_static = os.path.join(os.path.dirname(_here), 'static')
and having to be careful when I decide to refactor and put the view in another pkg or subpackage, or where-ever?
Something equivalent to request.static_path()
but instead of getting the url path
, to actually get a directory path:
request.static_file_path('static')
-> /path/to/site-packages/MyPkg/static
Thanks,
回答1:
You can use the pkg_resources
module to make paths that are relative to Python modules (and thus, independent of the module that retrieves them). For example:
import pkg_resources
print pkg_resources.resource_filename('os.path', 'static/favicon.ico')
# 'C:\\Python27\\lib\\static\\favicon.ico'
Just substitute os.path
with whatever module that is the parent of your static files.
EDIT: If you need to remember that 'static'
route mapped to 'MyPkg:static'
, then the easiest way is to save it in some dictionary in the first place:
STATIC_ROUTES = {'static': 'MyPkg:static'}
for name, path in STATIC_ROUTES.iteritems():
cfg.add_static_view(name=name, path=path)
and then simply retrieve the 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'))
If that's impossible, though (e.g. you don't have access to the cfg
object), you can retrieve this path, it's just quite painful. Here's a sample function that uses undocumented calls (and so may change in future Pyramid versions) and ignores some additional settings (like route_prefix
configuration variable):
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
In your case, it should work like this:
>>> get_static_path(request, 'static')
MyPkg:static/
来源:https://stackoverflow.com/questions/9289675/how-to-get-file-path-of-a-add-static-view-in-pyramid