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.
(If you were mad keen on Django’s shift to class-based views 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
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:
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. Hey! Nice threads! Also I have a cold.