How does URL dispatch work to serve static image files using Pyramid?

怎甘沉沦 提交于 2021-01-28 08:48:55

问题


I created a simple Pyramid app from the quick tutorial page here that has the following files relevant to the question:

  1. 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()
  1. 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}
  1. 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:

  1. Route config in tutorial/__init__.py: config.add_route('image', '/{filename}'). When I access localhost:6543/test.jpeg, I can see the image and things work as expected.
  2. Route config in tutorial/__init__.py: config.add_route('image', '/foo/{filename}'). When I access localhost:6543/foo/test.jpeg, I can see the image and things work as expected.
  3. Route config in tutorial/__init__.py: config.add_route('image', '/foo/bar/{filename}'). When I access localhost: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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!