让我们使用朋友的经典例子。
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。谁来阻止我。
发布于 2010-11-05 00:26:41
在the docs中查看ManyToManyField
的symmetrical
选项--听起来它可以做您想做的事情。
对于具体的操作方式,我会这样做
class LameUserExtension(User):
friends = ManyToManyField("self", through=Friendship)
class Friendship(models.Model):
# the stuff you had here
发布于 2014-07-24 04:51:11
我发现了一篇很好的文章,讨论了一段时间以前,基础知识如下:
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方法添加一点内容,以显式地处理关系的另一面:
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)
现在,每当我们创建一个单向的关系时,它的补充就会被创建(或删除)。由于关系是双向的,我们可以简单地使用:
def get_relationships(self, status):
return self.relationships.filter(
to_people__status=status,
to_people__from_person=self)
https://stackoverflow.com/questions/4098718
复制相似问题