I am trying to reduce my code writing in my Pyramid views and I'm trying to do it via a factory function.
Thus, instead of having something like this in my views.py:
class MyView(object):
def __init__(self, request):
self.request = request
@view_config(route_name='view', renderer='templates/view.pt')
def get(self):
return dict(msg='Hello!')
I try having something like this instead:
def factory(cls_name, rtn, rndr, myfun):
class Cls(object):
def __init__(self, request):
self.request = request
@myfun(route_name=rtn, renderer=rndr)
def get(self):
return dict(msg='Hello!')
Cls.__name__ = cls_name
return Cls
MyView = factory('MyView', 'view', 'templates/view.pt', view_config)
The reason is, obviously, that I'll end up having many classes that could utilise the same class functionality and I want to reduce my code writing. In case you ask me to use inheritance instead, then I'm stuck as to how to configure my derived classes to have a parameterised decorator (like myfun
). In essence, I need something like a template in C++.
So, even though the above second snippets does not generate any errors, and to me it seems to work just fine, when I try to run it in my test site (by replacing the second snippet with the second one), the routes are not understood by pyramid, so I'm getting a 404 error
. Based on the error, I presume that my problem is probably related with how pyramid parses the views.py file to find view_config
decorators, but I am not sure how to address it.
My __init__.py's main function is somehow like this:
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
config = Configurator(settings=settings)
config.add_route('view', '/')
config.scan()
return config.make_wsgi_app()
Any help would be greatly appreciated, so thanks all in advance!
The most likely cause of you code not working is the details of the scan process performed by Pyramid on startup to find and process all
@view_config
decorators. For one thing, the@view_config
docstring says:So I guess either your classes are created too late in the startup process or something in your dynamically-generated classes confuses venusian. If you have a look at
venusian
's source code you may be able to find the cause.However, I'd like to point out that the approach strikes me as a bit recursive... There are ways in Pyramid to register a view without any decorators. Then Pyramid authors added a layer of "syntax sugar" on top of that to simplify the most common use-case and be able to register a view by simply adding a decorator. Then you start fighting those decorators to be able to register a view by what looks like a function call :)
Have a look at pyramid.config.Configurator.add_view() - it already looks very much like your "factory function" but you may be able to write a simple wrapper around it if you want.