1

我目前正在构建一个具有朋友功能的网络应用程序(例如 Facebook 等)。

当好友发送好友请求时,会创建一个好友对象accepted = Falseaccepted设置为True当被请求的朋友接受请求时。

这是我的模型(大大简化了):

class Friendship(models.Model):
    sender = models.ForeignKey('Person', related_name='sender')
    receiver = models.ForeignKey('Person', related_name='receiver')
    accepted = models.BooleanField(default=False)

class Person(models.Model):
    person = models.OneToOneField(User)
    friends = models.ManyToManyField('self', through=Friendship)

我有这样的,所以我也可以管理朋友请求。

现在假设我有一个人约翰。我想获取 John 的所有朋友(例如,所有接受 John 的朋友请求的朋友,以及所有其朋友请求 John 已接受的朋友)。

这是我现在的做法:

def friends(person):
    friends = Friendship.objects.filter(sender=person, accepted=True) | Friendship.objects.filter(receiver=person, accepted=True)
    friends = [friendship.sender for friendship in friends if friendship.sender != person] + \
              [friendship.receiver for friendship in friends if friendship.receiver != person]
    return friends

对我来说,这看起来真的很丑陋,可能很慢而且效率低下。Django 有办法做这样的事情吗?

def friends(person):
    return person.friends.filter(accepted=True)

不幸的是,这个确切的代码不起作用。有没有更好的办法?

4

1 回答 1

1

我最近不得不运行一个非常相似的查询。像这样(或类似)的东西应该可以工作:

def friends(person):
    friends = Person.objects.filter(Q(sender__receiver=person, sender__accepted=True) | Q(receiver__sender=person, receiver__accepted=True))
    return friends

您可以使用 M2M 模型的related_name 属性对相关字段进行连接,例如Person.objects.filter(sender__accepted=True)

“朋友”是友谊关系中的另一个人。即如果你是接收者,朋友就是发送者,反之亦然。我还将重命名相关名称“sender”和“receiver”并添加“friend”,这样上面的查询就更清楚了。

于 2014-03-28T04:31:51.023 回答