In my app, users can follow other users, and get updates whenever the people they follow perform an activity.
I store the follow relationships in this manner:
class User(db.Model):
''' User details '''
username = db.StringProperty()
class Contacts(db.Model):
'''Store users contacts
parent= User (follower)
key_name= Users username (follower)
contacts = A list of keys of Users that a User follows '''
contacts = db.ListProperty(db.Key)
last_updated = db.DateTimeProperty(auto_now=True)
Getting followers, and Users that a user follows (followers & following):
'''Get Users that my_user follows'''
my_user = User().all().fetch(1)
contacts = Contacts.get_by_key_name(my_user.username).contacts
''' get my_user followers - copied from an answer here on stackoverflow '''
follower_index = models.Contacts.all(keys_only=True).filter('contacts =',my_user)
follower_keys = [f.parent() for f in follower_index]
followers = db.get(follower_keys)
So, I want to order my_user followers by follow date (which I don't track in the above models), but I'm not sure what is the best way to do that. Here are the options I can think of:
1) Instead of the current structure for Contacts(db.Model), use a "bridge" model:
class Contacts(db.Model):
follower = db.ReferenceProperty(User)
following = db.ReferenceProperty(User)
date_created = db.DateTimeProperty(auto_now_add=True)
However, I still have to figure out how to make sure that I have unique follower->following entities: follower=user1, following=user2 should not repeat. I can do that if I apply 2 filters to my query I think.
2) Keep the current model structure, but instead of having a list of keys in Contacts(db.Model), store a tuple: [user_key, date_created] as follows:
class Contacts(db.Model):
'''Store users contacts
parent= User (follower)
key_name= Users username (follower)
contacts = A list of Tuples: User.key(), date_created '''
contacts = db.StringListProperty()
last_updated = db.DateTimeProperty(auto_now=True)
However, this way i'll have to process the list of contacts: - I have to extract the User keys and date_created from each string in the StringList() - Then I can order the list of User keys by date created
3) Last solution (clearly not efficient): keep the original db structure, and store user follow activity in a separate Model - each follow action is stored separately with a date_created field. Use this table only to be able to order the list of user followers by date. This of course means that I'll do two datastore puts - one to Contacts() and another to FollowNewsFeed() as follows:
Class FollowNewsFeed(db.Model):
''' parent = a User follower'''
following = db.ReferenceProperty(User)
date_created = db.DateTimeProperty(auto_add_now=True)
Any insights on the best way to deal with this are highly appreciated :)
Thank you!