Оригинальный дизайн
Вот как я изначально настроил Models
:
class UserData(db.Model):
user = db.UserProperty()
favorites = db.ListProperty(db.Key) # list of story keys
# ...
class Story(db.Model):
title = db.StringProperty()
# ...
На каждой странице, где отображалась история, я запрашивал данные пользователя для текущего пользователя:
user_data = UserData.all().filter('user =' users.get_current_user()).get()
story_is_favorited = (story in user_data.favorites)
Новый дизайн
После просмотра этого выступления: Google I / O 2009 - масштабируемые, сложные приложения на App Engine , я подумал, можно ли настроить их более эффективно,
class FavoriteIndex(db.Model):
favorited_by = db.StringListProperty()
То же самое Story Model
, но я избавился от UserData Model
.Каждый экземпляр нового FavoriteIndex Model
имеет экземпляр Story
в качестве родителя.И каждый FavoriteIndex
хранит список идентификаторов пользователей в своем свойстве favorited_by
.
Если я хочу найти все истории, которые были добавлены определенным пользователем:
index_keys = FavoriteIndex.all(keys_only=True).filter('favorited_by =', users.get_current_user().user_id())
story_keys = [k.parent() for k in index_keys]
stories = db.get(story_keys)
Этот подход позволяет избежать сериализации / десериализации, которая иначе связана с ListProperty.
Эффективность против простоты
Я не уверен, насколько эффективен новый дизайн, особенно после того, как пользователь решит избрать 300истории, но вот почему мне это нравится:
Избранная история связана с пользователем, а не с ним user data
НаНа странице, где я отображаю story
, довольно просто спросить story
, была ли она добавлена (без вызова отдельной сущности, заполненной пользовательскими данными).
fav_index = FavoriteIndex.all().ancestor(story).get()
fav_of_current_user = users.get_current_user().user_id() in fav_index.favorited_by
Также легко получить список всех пользователей, которые одобрили историю (используя метод из # 2)
Есть ли более простой способ?
Пожалуйста, помогите,Как обычно это делается?