7

我是 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)
)

不保证正确性,只是为了说明我正在寻找的结果。

4

2 回答 2

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_useroruserBy__request_user是行不通的,因为那将是Friend您无法与 to 比较的参考User。我们在这里所做的是遵循反向关系Friend,然后一旦我们到达那里,查看好友请求中的其他用户是否是有问题的用户。

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

于 2012-10-12T20:56:31.787 回答
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)
于 2012-10-12T20:54:41.947 回答