Search code examples
pythonpython-3.xflaskpeeweeflask-peewee

Peewee Flask Trying to Return Data from a BooleanField


I'm trying to return the confirmed BooleanField of a user in the UserTable model (so I can deny access to some routes later) with this code:

models.py

class UserTable(UserMixin, Model):
    email = CharField(unique=True)
    password = CharField()
    confirmed = BooleanField()

    class Meta:
        database = db

app.py

@app.route('/isconfirmed/<email>')
def isconfirmed(email):
    return models.UserTable.get(models.UserTable.email == email).confirmed

When I try this however I receive: TypeError: 'bool' object is not callable

I've tried accessing email and password with:

return models.UserTable.get(models.UserTable.email == email).email etc. and it works just fine. I don't understand why it can't return a True or False from a BooleanField???

I'm using Postgres as my database if that is of any relevance / help.

Any help is appreciated greatly!!!


Solution

  • Here is what is happening.

    models.UserTable.get(models.UserTable.email == email).confirmed is a legitimate query and it returns a boolean - True or False.

    Now, referring to the view response type handling logic:

    The return value from a view function is automatically converted into a response object for you. If the return value is a string it’s converted into a response object with the string as response body, an 200 OK error code and a text/html mimetype. The logic that Flask applies to converting return values into response objects is as follows:

    • If a response object of the correct type is returned it’s directly returned from the view.

    • If it’s a string, a response object is created with that data and the default parameters.

    • If a tuple is returned the items in the tuple can provide extra information. Such tuples have to be in the form (response, status, headers) where at least one item has to be in the tuple. The status value will override the status code and headers can be a list or dictionary of additional header values.

    • If none of that works, Flask will assume the return value is a valid WSGI application and convert that into a response object.

    when Flask sees a boolean returned from a view, it tries to think about it as a WSGI application instance, but fails.

    You have to force it to be a string, if True or False is what you want to return from the view:

    @app.route('/isconfirmed/<email>')
    def isconfirmed(email):
        return str(models.UserTable.get(models.UserTable.email == email).confirmed)
    

    Also see a related issue resolved here: