Search code examples
pythongoogle-app-engineregistrationgoogle-cloud-datastoreuser-registration

Unable to check for already existing usernames google app engine


Here is my code to check for already existing usernames :

def post(self):
        have_error = False
        username = self.request.get('username')
        password = self.request.get('password')
        verify = self.request.get('verify')
        email = self.request.get('email')

        params = dict(username= username,
        email = email)

        usernames = db.GqlQuery(' select *  from Users where username = :1 ', username)


        if not valid_username(username):
            params['username_error'] = "Invalid username"
            have_error = True

        if usernames :
            params['username_error'] = 'Username already exists'
            have_error = True

With this code my form displays Username already exists for every username.

When the params['username_error'] = 'Username already exists' is changed to params['username_error'] = usernames ,

the message displayed in the username_error field is :

<google.appengine.ext.db.GqlQuery object at 0x10a4e030>


Solution

  • I'd change your check to:

    query = db.GqlQuery(' select *  from Users where username = :1 ', username)
    usernames = query.count(limit=2)
    

    Now, the if usernames: guard will have the effect you desire.

    The reason is simple: in your code, you build a query object, which you call usernames, but you never actually run that query -- you check the object for truthiness, which happens to hold (as does for almost all Python objects except empty containers and strings, None, zero numbers) but signifies nothing.

    Here, I run the query in the simplest way -- just count how many items it would return (just-counting is a bit faster than actually fetching them:-) and with a very low limit (since we only care about counts of 0, which is correct, and 1, which means a duplicate).

    Now usernames is a number counting how many other times that user name appears in the datastore (with 1 standing for "once or more":-) and the rest of your logic becomes accurate.