我正在使用带有MongoEngine的Flask创建一个应用程序来连接到MongoDB。 我的文件夹结构如下所示:
app/
__init__.py
mod_users/
__init__.py
constants.py
forms.py
models.py
views.py
mod_games/
__init__.py
constants.py
forms.py
models.py
views.py
让我们说我的用户和游戏模型如下:
mod_users / models.py
class User(db.Document):
email = db.EmailField()
username = db.StringField()
password = db.StringField()
mod_games / models.py
from app.mod_users.models import User
class Game(db.Document):
title = db.StringField()
creator = db.ReferenceField(User, reverse_delete_rule=db.CASCADE)
likes_count = db.IntField()
现在,我的问题是我希望用户拥有他喜欢的游戏列表。但是我不能使用引用字段,因为我必须导入Game才能创建循环导入。
这不会起作用:
from app.mod_games.models import Game
class User(db.Document):
email = db.EmailField()
username = db.StringField()
password = db.StringField()
liked_games = db.ListField(
db.ReferenceField(Game, reverse_delete_rule=db.PULL)
)
我考虑过在每个游戏中存储喜欢它的用户列表,然后在游戏中添加一个可以检索的静态方法 给定用户的喜欢游戏列表,但这似乎不是一种干净有效的解决方法。
答案 0 :(得分:1)
游戏和用户之间存在关系,任何数量的用户都可以喜欢一个游戏,一个用户可以喜欢任意数量的游戏。
这是典型的M:N关系,这是由关联类建模的(将其作为类建模规则)。
班级应该有:
元组用户 - 游戏必须是唯一的。
定义此类类时,可以从User和Game模块导入。
用户和游戏不得导入此关联类(否则您将再次进入循环引用问题)
答案 1 :(得分:1)
虽然你有一个答案--MongoEngine确实可以满足这个要求,因为你可以将类的字符串名称传递给参考字段,例如:
class User(db.Document):
email = db.EmailField()
username = db.StringField()
password = db.StringField()
liked_games = db.ListField(
db.ReferenceField('Game', reverse_delete_rule=db.PULL)
)
答案 2 :(得分:0)
与mentioned before一样,您可以将模型的字符串名称传递给参考字段。这是避免循环导入的第一件事:
class User(db.Document):
company = db.ReferenceField('Company')
但是,当您拥有使用某种模型的方法时,例如,汇总一些数据,上述方法无济于事-您仍然可能会遇到循环进口问题。要解决此问题,请尝试使用get_document
函数。参见下面的示例。
from mongoengine.base.common import get_document as get_model
class User(db.Document):
# fields definition omitted
def get_games(self):
Game = get_model('Game')
games = Game.objects.filter(user=self.pk)
# some code here