django ManyToMany 通过帮助
Posted
技术标签:
【中文标题】django ManyToMany 通过帮助【英文标题】:django ManyToMany through help 【发布时间】:2011-01-27 15:40:48 【问题描述】:嘿,我有一个关于人际关系的问题。
我希望用户有友谊。所以一个用户可以和另一个用户成为朋友。我假设我需要通过友谊表使用 ManyToManyField。但我无法让它工作。有什么想法吗?
这是我的模型。
class User(models.Model):
username = models.CharField(max_length=999)
password = models.CharField(max_length=999)
created_on = models.DateField(auto_now = False, auto_now_add = True)
updated_on = models.DateField(auto_now = True, auto_now_add = False)
friends = models.ManyToManyField('self')
pendingFriends = models.ManyToManyField('self', through='PendingFriendship', symmetrical=False, related_name='friend_requested')
class PendingFriendship(models.Model):
user = models.ForeignKey('User', related_name='user')
requested_friend = models.ForeignKey('User', related_name='requested_friend')
created_on = models.DateField(auto_now = False, auto_now_add = True)
updated_on = models.DateField(auto_now = True, auto_now_add = False)
谢谢
【问题讨论】:
【参考方案1】:documentation 中描述了多对多字段。做吧:
class User(models.Model):
username = models.CharField(max_length=999)
password = models.CharField(max_length=999)
created_on = models.DateField(auto_now = False, auto_now_add = True)
updated_on = models.DateField(auto_now = True, auto_now_add = False)
friends = models.ManyToManyField('self')
如果您想在关系中添加额外的字段,您只需使用through
。在this section 中描述了所有可能性的另一种描述。
当您将模型命名为 User 时,我假设您没有使用内置身份验证框架。但是如果你使用它,你不必自己实现认证,所以考虑一下。
更新: 你读过我链接到的部分吗?那里是这样描述的:
中间模型有一些限制:
您的中间模型必须包含一个 - 并且只有一个 - 目标模型的外键(在我们的示例中为 Person)。如果您有多个外键,则会引发验证错误。 您的中间模型必须包含一个 - 并且只有一个 - 源模型的外键(在我们的示例中为 Group)。如果您有多个外键,则会引发验证错误。 唯一的例外是通过中间模型与自身具有多对多关系的模型。在这种情况下,允许同一模型的两个外键,但它们将被视为多对多关系的两个(不同)边。 在使用中间模型定义从模型到自身的多对多关系时,您必须使用symmetrical=False
(请参阅model field reference)。
【讨论】:
我已经更新了这个例子,你的修改。但是我仍然需要额外的表来保存数据。 嗯,我更新了我的模型,它通过了验证。我添加了几个用户。并在用户 A 的模型上创建了一个 PendingFriendship 对象。这增加了友谊,但是用户 b 的对象没有得到友谊的另一面(我假设因为“对称”值是错误的)。我希望这种关系是对称的。有什么想法吗? 要使关系对称,您有两个选择:1) 创建另一个ManyToManyField
,将through_fields 选项设置为through_fields=('requested_friend', 'user')
; 2) 创建另一个PendingFriendship
对象,颠倒哪个朋友是user
,哪个朋友是requested_friend
。在你的情况下,我认为选项 1) 更有意义。【参考方案2】:
This blog 解释了您的需求。从博客中,您只需在这一行中更改相关名称:
pendingFriends = models.ManyToManyField('self', through='PendingFriendship', symmetrical=False, related_name='friend_requested')
进入:
related_name='friend_requested+'
但是,我仍然无法让它自动创建对称关系。
【讨论】:
以上是关于django ManyToMany 通过帮助的主要内容,如果未能解决你的问题,请参考以下文章
通过特定的 ManyToMany 对象订购 Django QuerySet