I am writing my website’s backend using Flask and Python 2.7, and have run into a bit of a problem. I like to use classes to enclose my functions, it makes things neat for me and helps me keep everything modular. One problem I’m having, though, is that the decorators flask uses for routing doesn’t preserve the self variable. I use this for accessing the loadDb method of the class that its in. See below. Anyone have any ideas why this is happening, and know how I could solve this, or even if there is a way to solve this?
class Test(object):
blueprint = Blueprint("Test", __name__)
def __init__(self, db_host, db_port):
self.db_host = db_host
self.db_port = db_port
def loadDb(self):
return Connection(self.db_host, self.db_port)
@blueprint.route("/<var>")
def testView(var): # adding self here gives me an error
return render_template("base.html", myvar=self.loadDb().find({"id": var})
There is an error if you add
selfbecause the method works the same as a function for the decorator, and the flask isn’t expecting a function with a first argumentself.Let’s look at the code of
route: https://github.com/pallets/flask/blob/master/src/flask/blueprints.py#L52It calls
self.add_url_rule(self being theBlueprint) with a few arguments, one of those being the function. What you want is to add a rule with the method bound to an instance ofTest(self.testView), not the method itself (Test.testview). This is tricky because the decorator is executed at the creation of the class, before any instance ever exist.The solution I can suggest, asside from avoiding to put your views as methods of a class, is to call yourself
blueprint.add_url_rulein the contructor ofTest(i.e., at the first point the instance ofTestis known.