All addresses to go to a single page (catch-all route to a single view) in Python Pyramid

一世执手 提交于 2019-12-10 17:02:16

问题


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

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