I have a catchall route that is catching my request before my call to add_route within an action created with a custom directive. How can I prevent that from happening? Ie. manually place the catchall route at the end of the route matching process or put my action's add_route at the front of the route matching process?
I tried swapping the order of the includes
between admin/routes.py
and routes.py
but that didn't seem to have an affect. A quick solution (and probably good idea thinking about it now) is to filter admin from the pattern in the catchall. But I feel like this is going to come up again where I cannot do that so I'm asking this question.
__init__.py
def main(global_config, **settings):
#...
config.include('.directives')
#...
config.include(".routes")
#...
for k in (".customer", ".admin"):
config.scan(k) # this picks up the admin/admin_routes.py
return config.make_wsgi_app()
admin/routes.py
def includeme(config):
config.add_dispatched_route(
"admin-plants-edit",
"/admin/plants/{id}",
'plant',
)
routes.py
def includeme(config):
#...
config.add_route("page-view", "/*url")
directives.py
from pyramid.config import PHASE0_CONFIG
from pyramid.httpexceptions import HTTPNotFound
def includeme(config):
def add_dispatched_route(config, route_name, route_pattern, dispatch_with):
def route_factory(request):
api = request.find_service(name=dispatch_with)
obj = api.by_id(request.matchdict["id"])
if not obj:
raise HTTPNotFound()
return obj
def route_pregenerator(request, elements, kw):
api = request.find_service(name=dispatch_with)
try:
obj = kw.pop(api.get_pregenerator_kw())
except KeyError:
pass
else:
kw["id"] = obj.id
return elements, kw
def register():
config.add_route(route_name, route_pattern, factory=route_factory, pregenerator=route_pregenerator)
config.action(('dispatched_route', route_name), register, order=PHASE0_CONFIG)
config.add_directive('add_dispatched_route', add_dispatched_route)
The way the phases work in Pyramid doesn't allow you to re-order actions within a phase. Basically imagine that every call to config.add_route
gets appended to a list, and then later that list is iterated in order to add the routes. You cannot inject a call to config.add_route
before another call to it.
However if you wrap every call to add_route in your own action, then you have an opportunity to defer everything, order things, and then call config.add_route
with each route in the order you wish.