abhimanyuPathania abhimanyuPathania - 1 month ago 6
Python Question

Checking username availability - Handling of AJAX requests (Google App Engine)

I want to add the 'check username available' functionality on my signup page using AJAX. I have few doubts about the way I should implement it.


  1. With which event should I register my AJAX requests? We can send the
    requests when user focus out of the 'username' input field (blur
    event) or as he types (keyup event). Which provides better user
    experience?

  2. On the server side, a simple way of dealing with requests would be
    to query my main 'Accounts' database. But this could lead to a lot
    of request hitting my database(even more if we POST using the keyup
    event). Should I maintain a separate model for registered usernames
    only and use that to get better results?

  3. Is it possible to use Memcache in this case? Initializing cache with
    every username as key and updating it as we register users and use a
    random key to check if cache is actually initialized or pass the
    queries directly to db.


Answer

Answers -

  1. Do the check on blur. If you do it on key up, you will be hammering your server with unnecessary queries, annoying the user who is not yet done typing, and likely lag the typing anyway.
  2. If your Account entity is very large, you may want to create a separate AccountName entity, and create a matching such entity whenever you create a real Account (but this is probably an unnecessary optimization). When you create the Account (or AccountName), be sure to assign id=name when you create it. Then you can do an AccountName.get_by_id(name) to quickly see if the AccountName has already been assigned, and it will automatically pull it from memcache if it has been recently dealt with.
  3. By default, GAE NDB will automatically populate memcache for you when you put or get entities. If you follow my advice in step 2, things will be very fast and you won't have to mess around with pre-populating memcache.

If you are concerned about 2 people simultaneously requesting the same user name, put your create method in a transaction:

@classmethod
@ndb.transactional()
def create_account(cls, name, other_params):
    acct = Account.get_by_id(name)
    if not acct:
        acct = Account(id=name, other param assigns)
        acct.put()