Class-based views for Bottle

I’m not convinced this is actually a good idea, but I have an approach for using class-based views as handlers for a route with [Bottle][bottle].

_(If you were mad keen on [Django’s][django] shift to [class-based views][cbv] you might reckon life wouldn’t be complete with a Bottle-based application until you employ classes for views. However Bottle’s use of decorators for tying URLs to views means it is less a natural fit than the same thing in Django.)_

The problem is that you can’t just decorate the method in your class using [`bottle.route`][route] because if you use that decorator on a method in a class you are telling Bottle to use the method before it has been bound to an instance of that class.

So although I wish it did, the following example will not work:

import bottle

class ViewClass(object):
@bottle.route(“/”)
def home_view(self):
return “My home page.”

obj = ViewClass()
bottle.run()

Running that will lead to errors about not enough arguments passed to the view method of your `ViewClass` instance.

Instead you need to register the route right after the object is created. This can be done in [the class’s `__new__` method][new]:

import bottle

class ViewClass(object):
def __new__(cls, *args, **kwargs):
obj = super(ViewClass, cls).__new__(cls, *args, **kwargs)
bottle.route(“/”)(obj.home_view)
return obj

def home_view(self):
return “My home page.”

obj = ViewClass()
bottle.run()

It works. It isn’t that pretty. You could achieve exactly the same thing by explicitly passing the `obj.home_view` method to `bottle.route` _after_ the instance is created. The advantage to doing this in the `__new__` method is it will happen automatically whenever `ViewClass` is instantiated.

And if you go down this path then [you should be aware of threads][threads]. Hey! Nice threads! Also I have a cold.

[bottle]: http://bottle.paws.de/
[cbv]: http://docs.djangoproject.com/en/dev/topics/class-based-views/
[django]: http://www.djangoproject.com/
[route]: http://bottle.paws.de/docs/dev/api.html#routing
[new]: http://docs.python.org/reference/datamodel.html#object.__new__
[threads]: http://bottle.paws.de/docs/dev/tutorial.html#accessing-request-data

Leave a Reply

Your email address will not be published. Required fields are marked *