首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何建模与django的对称关系?

如何建模与django的对称关系?
EN

Stack Overflow用户
提问于 2010-11-05 00:12:37
回答 2查看 3.9K关注 0票数 22

让我们使用朋友的经典例子。

代码语言:javascript
复制
class Friendship(models.Model):
    user1 = models.ForeignKey(User, related_name='friends1')
    user2 = models.ForeignKey(User, related_name='friends2')
    handshakes = models.PositiveIntegerField()
    hugs = models.PositiveIntegerField()
    # other silly data

友谊中的两个朋友(user1和user2)应该是完全平等的。我应该能够说(user1,user2)是unique_together,而不必担心(user2,user1)意外出现。我应该能够很容易地获得给定用户的所有朋友,但是相反,我必须编写一个自定义管理器或创建一些其他方法来获得所有的友谊,其中该用户是关系中的user1,以及该用户是user2的所有友谊。

我正在考虑尝试编写我自己的SymmetricKey。谁来阻止我。

EN

回答 2

Stack Overflow用户

发布于 2010-11-05 00:26:41

the docs中查看ManyToManyFieldsymmetrical选项--听起来它可以做您想做的事情。

对于具体的操作方式,我会这样做

代码语言:javascript
复制
class LameUserExtension(User):
    friends = ManyToManyField("self", through=Friendship)

class Friendship(models.Model):
    # the stuff you had here
票数 8
EN

Stack Overflow用户

发布于 2014-07-24 04:51:11

我发现了一篇很好的文章,讨论了一段时间以前,基础知识如下:

代码语言:javascript
复制
class Person(models.Model):
    name = models.CharField(max_length=100)
    relationships = models.ManyToManyField('self', through='Relationship', 
                                           symmetrical=False, 
                                           related_name='related_to+')

RELATIONSHIP_FOLLOWING = 1
RELATIONSHIP_BLOCKED = 2
RELATIONSHIP_STATUSES = (
    (RELATIONSHIP_FOLLOWING, 'Following'),
    (RELATIONSHIP_BLOCKED, 'Blocked'),
)

class Relationship(models.Model):
    from_person = models.ForeignKey(Person, related_name='from_people')
    to_person = models.ForeignKey(Person, related_name='to_people')
    status = models.IntegerField(choices=RELATIONSHIP_STATUSES)

请注意related_name末尾的加号。这向Django表明不应该暴露反向关系。因为关系是对称的,所以这是期望的行为,毕竟,如果我是A的朋友,那么A也是我的朋友。Django不会为您创建对称关系,因此需要向add_relationship和remove_relationship方法添加一点内容,以显式地处理关系的另一面:

代码语言:javascript
复制
def add_relationship(self, person, status, symm=True):
    relationship, created = Relationship.objects.get_or_create(
        from_person=self,
        to_person=person,
        status=status)
    if symm:
        # avoid recursion by passing `symm=False`
        person.add_relationship(self, status, False)
    return relationship

def remove_relationship(self, person, status, symm=True):
    Relationship.objects.filter(
        from_person=self, 
        to_person=person,
        status=status).delete()
    if symm:
        # avoid recursion by passing `symm=False`
        person.remove_relationship(self, status, False)

现在,每当我们创建一个单向的关系时,它的补充就会被创建(或删除)。由于关系是双向的,我们可以简单地使用:

代码语言:javascript
复制
def get_relationships(self, status):
    return self.relationships.filter(
        to_people__status=status, 
        to_people__from_person=self)

来源:Self-referencing many-to-many through

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4098718

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档