I am writing a Tornado app in which a user can maintain his products wishlist. There are two collections, users
and products
. As the names imply, the users
collections will contain users info and the products
collections will contain the URLs.
Typically a user
document in users
collection will contain the following fields:
email_id
name
tracked_products
The tracked_products
here is a list which maintains the wishlist. It contains the ObjectId
mapped to URLs in products
collection. To make it clear, when two users add the same product URL, in their respective user documents instead of containing the URL, they will have the ObjectId
of this URL, which is the ID of the URL in the products
collection.
To find tracked_products of a specific user:
search_user = user_db.find_one({'email_id': user_email})
search_user['tracked_products']
above will return to me list of ObjectId
s.
To add a product URL to the user's wishlist:
product_doc = product_db.find_one({'url': url})
if not product_doc:
# code needs to be added here to get product name from url
product_id = str(product_db.insert({'product_name': 'iPad', 'url': url})
else:
product_id = product_doc['_id']
user_db.update({'email_id': user_email}, {'$addToSet': {'tracked_products': ObjectId(product_id)}})
The following is the code when user wants to remove a URL from his wishlist. Do note that he will send the ObjectId
instead of the URL, he intends to remove. This may seem less intuitive. The user will actually never know the ObjectId
s, but the page rendered to him which displays the wishlist, will make call when user wants to delete the URL (am I clear here?):
user_db.update({'email_id': user_email}, {'$pull': {'tracked_products': ObjectId(product_id)}})
And here is my actual Tornado app code. I am not using any templating as of now, will add that later. Also ignore the repeated user_db = self.application.db.users
statement which is present in all handlers (which should not, may app can have this variable). And one more thing: I access the current logged in user's email ID every time by a cookie.
Is there any way to avoid this? Can I have some global variable which stores user email ID every time the user is logged in?
class ProductsDisplayHandler(BaseHandler):
@tornado.web.authenticated
def get(self):
user_email = self.get_secure_cookie('trakr')
user_db = self.application.db.users
search_user = user_db.find_one({'email_id': user_email})
self.write(str(search_user.get('tracked_products', None)))
class ProductAddHandler(BaseHandler):
@tornado.web.authenticated
def get(self, url):
user_email = self.get_secure_cookie('trakr')
user_db = self.application.db.users
product_db = self.application.db.products
product_doc = product_db.find_one({'url': url})
if not product_doc:
product_id = str(product_db.insert({'product_name': 'iPad', 'url': url}))
else:
product_id = product_doc['_id']
user_db.update({'email_id': user_email}, {'$addToSet': {'tracked_products': ObjectId(product_id)}})
class ProductDelHandler(BaseHandler):
@tornado.web.authenticated
def get(self, product_id):
user_email = self.get_secure_cookie('trakr')
user_db = self.application.db.users
user_db.update({'email_id': user_email}, {'$pull': {'tracked_products': ObjectId(product_id)}})
self.redirect('/products')
return