How to generate json
views from a list of strings with Pyramid?
With the following attempt only the view of the last element of the list is generated; jkl_json
in this case, the others produce 404 Not Found
.
names = ['abc', 'def', 'ghi', 'jkl']
for nm in names:
@view_config(route_name='{}_json'.format(nm),
renderer='json',)
def names_json(request):
nm_cls = globals()[nm.title()]
...
This does actually work with html views; but not with json views.
This happens because Pyramid uses the Venusian library for decorators; they attach information to functions instead of registering the view instantly. This information is later processed by config.scan
, and only then is the route actually registered. In your code you're replacing the names_json
function with another function by the same name on each loop. Since only last of them is visible in the module, with only the last view_config
data attached to it, this is what Venusian picks up when scanning.
You should instead apply the decorators to exactly one function. If you remember that
@view_config(route_name='foo')
def bar(request):
return Response()
is just syntactic sugar for
def bar(request):
return Response()
bar = view_config(route_name='foo')
you can do
def names_json(request):
...
names = ['abc', 'def', 'ghi', 'jkl']
for nm in names:
names_json = view_config(route_name='{}_json'.format(nm),
renderer='json')(names_json)
On the other hand, if the paths are like this, perhaps you can just use a single route for all of them:
config.add_route('names', '/foo/{name:abc|def|ghi|jkl}.json')
where the route would match any of /foo/abc.json
, /foo/def.json
, /foo/ghi.json
or /foo/jkl.json
, and the name would be available as request.matchdict['name']
within the view.