Dealing with a user’s assets.
Tuesday, November 1st, 2011With everyone building social sites I find it funny that no python framework seems handle user profiles very well.
Normally the code would written as followed:
__init__.py
config.add_route('profile_view', '/:id')
config.add_route('profile_photos', '/:id/photos')
views/profile.py
@view_config(route_name='profile_view', renderer='profile/view.jinja2')
def view(request):
    profile = AuthUser.get_by_id(request.matchdict.get('id'))
    return {
        'profile': profile,
    }
@view_config(route_name='profile_photos', renderer='profile/photos.jinja2')
def photos(request):
    profile = AuthUser.get_by_id(request.matchdict.get('id'))
    return {
        'profile': profile,
    }
Now this code isn’t very DRY, so this is where pyramid_handlers comes in handy.
Same code, using pyramid_handlers.
__init__.py
config.add_handler('profile_view', '/:id', handler='project.views.profile.Profile', action='view')
config.add_handler('profile_photos', '/:id/photos', handler='project.views.profile.Profile', action='photos')
Adding multiple add_handler isn’t very DRY either, so condense the code more.
__init__.py
config.add_handler('profile', '/:id/:action', handler='project.views.profile.Profile')
views/profile.py
class Profile(object):
    def __init__(self, request):
        self.request = request
        self.extra = {}
        self.extra['profile'] = AuthUser.get_by_id(request.matchdict.get('id'))
    
    @action(renderer='profile/view.jinja2')
    def view(self):
        return dict({}, **self.extra)
    @action(renderer='profile/photos.jinja2')
    def photos(self):
        return dict({}, **self.extra)
In response to Wayne’s comment:
This way does use more add_route calls, but it also removes a dependency.
__init__.py
config.add_route('profile_view', '/:id')
config.add_route('profile_photos', '/:id/photos')
views/profile.py
class Profile(object):
    def __init__(self, request):
        self.request = request
        self.extra = {}
        self.extra['user'] = AuthUser.get_by_id(request.matchdict.get('id'))
        
    @view_config(route_name='profile_view', renderer='profile/view.jinja2')
    def view(self):
        return dict({}, **self.extra)        
    @view_config(route_name='profile_photos', renderer='profile/photos.jinja2')
    def photos(self):
        return dict({}, **self.extra)