Django的复杂查询(来自所有朋友的帖子)

时间:2012-10-12 20:50:30

标签: python django django-models

我是Python和Django的新手,所以请耐心等待我。

我有以下型号:

class User(models.Model):
   name = models.CharField(max_length = 50)
   ...

class Post(models.Model):
   userBy = models.ForeignKey(User, related_name='post_user')
   userWall = models.ForeignKey(User, related_name='receive_user')
   timestamp = models.DateTimeField()
   post = models.TextField()

class Friend(models.Model):
   user1 = models.ForeignKey(User, related_name='request_user')
   user2 = models.ForeignKey(User, related_name='accept_user')
   isApproved = models.BooleanField()
   class Meta:
      unique_together = (('user1', 'user2'), )

我知道这可能不是用Django处理它的最好/最简单的方法,但我是这样学习的,我想保持这样。

现在,我想做的就是从一个人那里得到所有帖子,这是朋友。现在的问题是如何使用Django过滤器?

我认为在SQL中它看起来像这样:

SELECT p.* FORM Post p, Friend f 
WHERE p.userBy=THEUSER OR (
    (f.user1=THEUSER AND f.user2=p.userBy) OR
    (f.user2=THEUSER AND f.user1=p.userBy)
)

不保证正确性,只是想知道我正在寻找的结果。

2 个答案:

答案 0 :(得分:8)

from django.db.models import Q

Post.objects.filter( \
    Q(userBy=some_user) | \
    Q(userBy__accept_user__user1=some_user) | \
    Q(userBy__request_user__user2=some_user)).distinct()

<强>更新

对不起,那是我的错。我没注意你的related_name值。请参阅上面的更新代码单独使用userBy__accept_useruserBy__request_user将不起作用,因为这将是Friend的引用,您无法将其与User进行比较。我们在这里做的是遵循与Friend的反向关系,然后一旦我们在那里,看看朋友请求中的其他用户是否是相关用户。

这也说明了适当描述反向关系的重要性。许多人犯了你在这里犯的同样的错误并在他们创建FK的模型之后将related_name命名为(User),实际上,当我们谈论逆转FK时,我们现在谈论Friend。简而言之,您的相关名称会更有意义:friend_requestsaccepted_friends

答案 1 :(得分:0)

(with User u)
friends_u1 = Friend.objects.filter(user1 = u).getlist('user2_id', flat=True)
friends_u2 = Friend.objects.filter(user2 = u).getlist('user1_id', flat=True)
friends_and_user = friends_u1+friends_u2+u.id

Post.objects.filter(userBy__id__in = friends_and_user)