我无法让Django ORM查询正常工作。我有这个友谊模型:
class Friendship(models.Model):
user1 = models.ForeignKey(User, related_name='friendships1')
user2 = models.ForeignKey(User, related_name='friendships2')
class Meta:
unique_together = ('user1', 'user2',)
要查找给定用户的朋友,我们必须检查user1和user2,因为我们永远无法确定他们将在哪个方面建立关系。因此,为了获得给定用户的所有朋友,我使用以下查询:
user = request.user
User.objects.filter(
Q(friendships1__user2=user, friendships1__status__in=statuses) |
Q(friendships2__user1=user, friendships2__status__in=statuses)
)
在我看来,它应该可行,但事实并非如此。它给了我重复。这是它生成的SQL:
SELECT auth_user.*
FROM auth_user
LEFT OUTER JOIN profile_friendship ON (auth_user.id = profile_friendship.user1_id)
LEFT OUTER JOIN profile_friendship T4 ON (auth_user.id = T4.user2_id)
WHERE (
(profile_friendship.status IN ('Accepted') AND profile_friendship.user2_id = 1 )
OR (T4.user1_id = 1 AND T4.status IN ('Accepted'))
);
这是我想要的SQL,它会产生正确的结果:
SELECT f1.id as f1id, f2.id AS f2id, u.*
FROM auth_user u
LEFT OUTER JOIN profile_friendship f1 ON (u.id = f1.user1_id AND f1.user2_id = 1 AND f1.status IN ('Accepted'))
LEFT OUTER JOIN profile_friendship f2 ON (u.id = f2.user2_id AND f2.user1_id = 1 AND f2.status IN ('Accepted'))
WHERE f1.id IS NOT NULL OR f2.id IS NOT NULL
我知道我可以在原始查询中执行此操作,但后来我认为我无法链接。有没有一个很好的干净方法来做到这一点,而不是原始的?
答案 0 :(得分:3)
您应该使用ManyToManyField.symmetrical
答案 1 :(得分:1)
简单的解决方案:
user = request.user
User.objects.filter(
Q(friendships1__user2=user, friendships1__status__in=statuses) |
Q(friendships2__user1=user, friendships2__status__in=statuses)
).distinct()
任何人都知道有什么缺点吗?