您好我正在尝试构建一个类似下面的模型的应用程序:-(虽然很容易将两个模型合并为一个并使用它们,但这在实际的应用程序中是不可行的)< / p>
class User(db.Model):
username=db.StringProperty()
email=db.StringProperty()
class UserLikes(db.Model):
username=db.StringProperty()
food=db.StringProperty()
目标 - 登录后的用户输入他喜欢的食物,然后应用程序返回所有喜欢该食物的其他用户。 现在假设用户Alice输入她喜欢的“Pizzas”,它会存储在数据存储区中。她退出并再次登录。此时,我们向数据存储区查询她喜欢的食物,然后再次查询所有喜欢该食物的用户。如您所见,这是两个数据存储查询,这不是最好的方法。我相信肯定会有更好的方法来做到这一点。有人可以帮忙。
[更新: - 或者可以做这样的事情,我改变第二个模型,使用户名成为一个多值属性,其中所有喜欢这些食物的用户都可以存储..但是我在这里有点不清楚] < / p>
[编辑:-Hi感谢您的回复,但我发现这两个解决方案在这里有点过分。我试着像下面这样做。请你看看这个和善意的建议。我维护了相同的两个表,但是如下所示进行了更改: -
class User(db.Model):
username=db.StringProperty()
email=db.StringProperty()
class UserLikes(db.Model):
username=db.ListProperty(basestring)
food=db.StringProperty()
现在当2个用户更新他们喜欢的相同食物时,它会像
一样存储'pizza'----&gt; '爱丽丝', '鲍勃'
我在这里检索数据的db查询变得非常容易
query=db.Query(UserLikes).filter('username =','Alice').get()
然后我可以像
那样迭代 for elem in query.username:
print elem
现在如果有两种食物如下: -
'pizza' ----> 'Alice','Bob'
'bacon'----->'Alice','Fred'
我使用与上面相同的查询,并迭代查询,然后迭代用户名。
我对此很新,意识到这可能是错的。请建议!
答案 0 :(得分:2)
除了您拥有的关系模型之外,您还可以通过其他两种方式处理此问题,具体取决于您的确切用例。您在更新中有一个好主意,使用ListProperty。查看Brett Slatkin在Relation Indexes上的taslk的某些背景。
您可以在包含食物清单的用户上使用子实体(关系索引):
class UserLikes(db.Model):
food = db.StringListProperty()
然后,当您创建UserLikes实例时,您将定义与其相关的用户作为父实例:
likes = UserLikes(parent=user)
这使您可以很好地查询喜欢特定食物的其他用户:
like_apples_keys = UserLikes.all(keys_only=True).filter(food='apples')
user_keys = [key.parent() for key in like_apples_keys]
users_who_like_apples = db.get(user_keys)
然而,更适合你的应用的是将关系变成食物的孩子:
class WhoLikes(db.Model):
users = db.StringListProperty()
创建类似时,将key_name设置为食物名称:
food_i_like = WhoLikes(key_name='apples')
现在,让所有喜欢苹果的用户:
apple_lover_key_names = WhoLikes.get_by_key_name('apples')
apple_lovers = UserModel.get_by_key_names(apple_lover_key_names.users)
让所有喜欢与用户相同的用户:
same_likes = WhoLikes.all().filter('users', current_user_key_name)
like_the_same_keys = set()
for keys in same_likes:
like_the_same_keys.union(keys.users)
same_like_users = UserModel.get_by_key_names(like_the_same_keys)
如果你有很多喜欢,或者有很多相同喜欢的用户,你需要对这个过程进行一些调整。您将无法获取1,000个用户。
答案 1 :(得分:1)
食物和用户关系是一个所谓的Many-to-Many relationship,通过连接表进行简单处理;在这种情况下,链接用户和食物的db.Model。 像这样:
class User(db.Model):
name = db.StringProperty()
def get_food_I_like(self):
return (entity.name for entity in self.foods)
class Food(db.Model):
name = db.StringProperty()
def get_users_who_like_me(self):
return (entity.name for entity in self.users)
class UserFood(db.Model):
user= db.ReferenceProperty(User, collection_name='foods')
food = db.ReferenceProperty(Food, collection_name='users')
对于给定用户的实体,您可以通过以下方式检索首选食物:
userXXX.get_food_I_like()
对于给定食物的实体,您可以通过以下方式检索喜欢该食物的用户:
foodYYY.get_users_who_like_me()
还有另一种方法可以处理在db.ListProperty()
内存储密钥列表的多对多关系。
class Food(db.Model):
name = db.StringProperty()
class User(db.Model):
name = db.StringProperty()
food = db.ListProperty(db.Key)
请记住,ListProperty限制为5.000键或再次,您无法添加完全适合连接表的有用属性(例如:表示用户喜欢食物的数量的星数)。