我想要创建电影数据库,用户可以在其中标记他/她观看和喜欢的电影:
class Movies(ndb.Model):
watched = ndb.UserProperty()
liked = ndb.UserProperty()
那能行吗?我用谷歌账号。以后我应该如何选择所有用户喜欢的电影?
Upd.我遵循了方法,并使用以下代码保存用户选择:
user = users.get_current_user()
if user:
userschoices = models.UsersChoices(
movie=ndb.Key(models.Movies, movie_id), # TODO: what if movie_id is wrong?
watched=True,
user_id=user.user_id()
)
try:
userschoices.put()
self.response.out.write('1')
except:
self.response.out.write('0')
但是如果用户做了几次选择,那么几条记录就会添加到数据存储中.把用户id和电影id保存为密钥不是更好吗?
userschoices = models.UsersChoices.get_by_id(user.user_id() + '-' + movie_id)
if userschoices is None:
userschoices = models.UsersChoices(id=user.user_id() + '-' + movie_id)
userschoices.movie = ndb.Key(models.Movies, movie_id) # TODO: what if movie_id is wrong?
userschoices.user_id = user.user_id()
if option == 'liked':
userschoices.liked = True
elif option == 'watched':
userschoices.watched = True
但是,使用这种方法--如果我不传递liked
--那么它就用None
覆盖它的值(与watched
相同,如果没有传递,则使用None
)。
发布于 2012-07-30 07:43:18
我将使用两种不同的模型,一种存储所有Movies
详细信息,另一种存储UserChoices
:
class Movies(ndb.Model):
title = ndb.StringProperty(required=True)
director = ndb.StringProperty()
whatever = ndb.StringProperty()
class UsersChoices(ndb.Model):
movie = ndb.KeyProperty(kind=Movies, required=True)
watched = ndb.BooleanProperty(required=True)
liked = ndb.BooleanProperty(required=True)
user_id = ndb.StringProperty(required=True)
@classmethod
def get_liked_movies(cls, user_id):
return cls.query(cls.user_id == user_id, cls.liked == true).fetch(10)
@classmethod
def get_watched_movies(cls, user_id):
return cls.query(cls.user_id == user_id, cls.watched == true).fetch(10)
@classmethod
def get_by(cls, user_id, movie_key):
return cls.query(cls.user_id == user_id, cls.movie == movie_key).get()
如果您需要存储有关用户的信息,您应该创建您的UserInfo
模型,使用应用程序所需的所有细节属性(由user_id
从用户API键控)。
class UserInfo(ndb.Model):
#Keyed by user_id
nickname = ndb.StringProperty()
email = ndb.StringProperty()
要创建一个新的UserInfo
,可以这样做:
from google.appengine.api import users
user = users.get_current_user()
userinfo = UserInfo(
id = user.user_id(),
nickname = user.keyname(),
email = user.email()
)
userinfo.put()
然后,当用户登录时,使用他/她的user_id
检索观看/喜欢的电影。
from google.appengine.api import users
user = users.get_current_user()
userinfo = ndb.Key(UserInfo, user.user_id()).get()
watched_movies = UsersChoices.get_watched_movies(userinfo.key.id())
liked_movies = UsersChoices.get_liked_movies(userinfo.key.id())
发布于 2012-07-30 08:20:19
看来你是在试图塑造一种多对多的关系。有几种方法可以建立这种关系的模型 (请参阅多到多部分)。另见尼克的博客。(不幸的是,这些引用都不是为NDB编写的,因此,例如,,即反向引用。但是,它们在向您展示如何将数据分解为不同的模型时仍然很有用。)
有一种方法可以使用“连接表”/“关系模型”来实现:
class Movie(ndb.Model):
title = ndb.StringProperty(required=True)
class LikedMovie(ndb.Model):
movie = ndb.KeyProperty(kind=Movie, required=True)
user = ndb.StringProperty(required=True) # user.user_id()
class WatchedMovie(ndb.Model):
movie = ndb.KeyProperty(kind=Movie, required=True)
user = ndb.StringProperty(required=True) # user.user_id()
...
movies_user_likes = LikedMovie.query(LikedMovie.user == user.user_id()).fetch()
根据应用程序支持的用户数量和更新数据库的频率,使用重复属性(即用户列表)而不是使用联接表可能更有效:
class Movie(ndb.Model):
title = ndb.StringProperty(required=True)
users_who_watched = ndb.StringProperty(repeated=True) # list of user.user_id()s
users_who_liked = ndb.StringProperty(repeated=True) # list of user.user_id()s
...
movies_user_likes = Movie.query(Movie.users_who_liked == user.user_id()).fetch(projection=[Movie.title])
请注意,我在上面使用了一个投影查询,这样就不会在查询结果中返回users_who_watched列表。您可能不需要这些,这将大大加快抓取速度。
如果您期望,例如,少于1,000个用户观看或喜欢一部特定的电影,列表方法可能会更好。
有关更高级的技术,请参见在App上构建可扩展的复杂应用程序,其中Brett演示如何使用父键将重复/列表属性移动到单独的模型中。
https://stackoverflow.com/questions/11711077
复制相似问题