问题
I am trying to alter the Pyramid hello world example so that any request to the Pyramid server serves the same page. i.e. all routes point to the same view. This is what iv got so far:
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
def hello_world(request):
return Response('Hello %(name)s!' % request.matchdict)
if __name__ == '__main__':
config = Configurator()
config.add_route('hello', '/*')
config.add_view(hello_world, route_name='hello')
app = config.make_wsgi_app()
server = make_server('0.0.0.0', 8080, app)
server.serve_forever()
All iv done is change the line (from the hello world example):
config.add_route('hello', '/hello/{name}')
To:
config.add_route('hello', '/*')
So I want the route to be a 'catch-all'. Iv tried various variations and cant get it to work. Does anyone have any ideas?
Thanks in addvance
回答1:
The syntax for the catchall route (which is called "traversal subpath" in Pyramid) is *subpath
instead of *
. There's also *traverse
which is used in hybrid routing which combines route dispatch and traversal. You can read about it here: Using *subpath in a Route Pattern
In your view function you'll then be able to access the subpath via request.subpath
, which is a tuple of path segments caught by the catchall route. So, your application would look like this:
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
def hello_world(request):
if request.subpath:
name = request.subpath[0]
else:
name = 'Incognito'
return Response('Hello %s!' % name)
if __name__ == '__main__':
with Configurator() as config:
config.add_route('hello', '/*subpath')
config.add_view(hello_world, route_name='hello')
app = config.make_wsgi_app()
server = make_server('0.0.0.0', 8081, app)
server.serve_forever()
Don't do it via custom 404 handler, it smells of PHP :)
回答2:
You could create a custom error handler (don't remember off the top of my head but it was in the Pyramid docs) and capture HTTP 404 errors, and redirect/render your catch-all route from there.
The link I'm thinking of: http://docs.pylonsproject.org/projects/pyramid//en/latest/narr/hooks.html
I've done something like this:
from pyramid.view import (
view_config,
forbidden_view_config,
notfound_view_config
)
from pyramid.httpexceptions import (
HTTPFound,
HTTPNotFound,
HTTPForbidden,
HTTPBadRequest,
HTTPInternalServerError
)
import transaction
import traceback
import logging
log = logging.getLogger(__name__)
#region Custom HTTP Errors and Exceptions
@view_config(context=HTTPNotFound, renderer='HTTPNotFound.mako')
def notfound(request):
if not 'favicon' in str(request.url):
log.error('404 not found: {0}'.format(str(request.url)))
request.response.status_int = 404
return {}
I think you should be able to redirect to a view from within there.
来源:https://stackoverflow.com/questions/32381041/all-addresses-to-go-to-a-single-page-catch-all-route-to-a-single-view-in-pytho