Django通过表属性查询

时间:2014-03-28 02:03:35

标签: python django models querying

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

当朋友发送好友请求时,会使用accepted = False创建友谊对象。 accepted被设置为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)

我喜欢这样,所以我也可以管理好友请求。

现在让我们说我有个约翰。我希望得到约翰的所有朋友(例如,所有接受约翰朋友请求的朋友,以及朋友请求约翰接受的所有朋友)。

以下是我现在的表现:

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)

不幸的是,这段确切的代码并不起作用。还有更好的方法吗?

1 个答案:

答案 0 :(得分: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”,以便上面的查询更清晰。