问题
I created a simple Pyramid app from the quick tutorial page here that has the following files relevant to the question:
tutorial/__init__.py
:
from pyramid.config import Configurator
def main(global_config, **settings):
config = Configurator(settings=settings)
config.include('pyramid_chameleon')
config.add_route('home', '/')
config.add_route('hello', '/howdy')
config.add_static_view(name='static', path='tutorial:static')
config.add_route('image', '/{filename}')
config.scan('.views')
return config.make_wsgi_app()
tutorial/views/views.py
:
from pyramid.view import (
view_config,
view_defaults
)
@view_defaults(renderer='../templates/home.pt')
class TutorialViews:
def __init__(self, request):
self.request = request
@view_config(route_name='home')
def home(self):
return {'name': 'Home View'}
@view_config(route_name='hello')
def hello(self):
return {'name': 'Hello View'}
@view_config(route_name='image', renderer='../templates/image.pt')
def image(request):
filename = request.matchdict.get('filename')
return {'name': 'Hello View', 'filename': filename}
tutorial/templates/image.pt
:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Quick Tutorial: ${name}</title>
<link rel="stylesheet"
href="${request.static_url('tutorial:static/app.css') }"/>
</head>
<body>
<h1>Hi ${name}</h1>
<img src="../static/images/${filename}">
</body>
</html>
I have placed an image file at the path tutorial/static/images/test.jpeg
. Now, here are the 3 cases I tried and the results when I started the server using pserve development.ini --reload
:
- Route config in
tutorial/__init__.py
:config.add_route('image', '/{filename}')
. When I accesslocalhost:6543/test.jpeg
, I can see the image and things work as expected. - Route config in
tutorial/__init__.py
:config.add_route('image', '/foo/{filename}')
. When I accesslocalhost:6543/foo/test.jpeg
, I can see the image and things work as expected. - Route config in
tutorial/__init__.py
:config.add_route('image', '/foo/bar/{filename}')
. When I accesslocalhost:6543/foo/bar/test.jpeg
, this is when I don't see the image.
In case 3) above, I tried a few things and I can see the image only when in the file tutorial/templates/image.pt
, I change the line <img src="../static/images/${filename}">
to <img src="../../static/images/${filename}">
. I cannot seem to understand why Pyramid is forcing me to add another directory layer in my template to see the image. Can anyone explain why?
回答1:
It's not really clear to me why you would put static assets in three different places in this minimal example.
With the configuration you provided in example 3, you can modify your template as follows.
<img src="${request.static_path("tutorial:static/images/")}${filename}">
That should then generate the HTML to:
<img src="http://example.com/static/images/test.jpeg">
Another option is to create a "catch all" route at the end of your routing table, which would serve the static assets directly without using a template.
from pyramid.static import static_view
static_view = static_view('/path/to/static/dir', use_subpath=True)
# .. every other add_route declaration should come
# before this one, as it will, by default, catch all requests
config.add_route('catchall_static', '/*subpath')
config.add_view('myapp.static.static_view', route_name='catchall_static')
It is also OK to configure multiple static routes, if that is what you want.
See the full documentation of Static Assets.
来源:https://stackoverflow.com/questions/63541315/how-does-url-dispatch-work-to-serve-static-image-files-using-pyramid