【问题标题】:Django inner join onDjango内部加入
【发布时间】:2019-12-29 16:05:17
【问题描述】:

首先,我想说我已经检查了所有类似的问题,但没有一个是我问题的答案。

我有FriendUser 模型。

朋友模型

class Friend(models.Model):
    id = models.BigAutoField(primary_key=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE, unique=False, related_name='%(class)s_requests_created')
    following = models.ForeignKey(User, on_delete=models.CASCADE, unique=False, null=True, blank=True)
    accepted = models.BooleanField(default=False)
    deleted_at = models.DateTimeField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

用户模型

class User(AbstractBaseUser):
    id = models.BigAutoField(primary_key=True)
    username = models.CharField(max_length=30, unique=True)
    email = models.EmailField(max_length=191, unique=True)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30, blank=True)
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)

让我们考虑 3 个用户。用户 A、B、C。B 关注 AC 关注 B(我是C 我想要实现的是根据用户B 获取用户A,即关注用户A

相当简单的查询,但使用 Django QuerySet 有点复杂。

这是我的查询

SELECT U2.username FROM `accounts_friend`

INNER JOIN `accounts_user` U1 ON accounts_friend.following_id = U1.id AND U1.is_active = 1
INNER JOIN `accounts_friend` F1 ON accounts_friend.following_id = F1.user_id AND F1.accepted = 1 AND F1.deleted_at IS NULL AND F1.user_id != F1.following_id
INNER JOIN `accounts_user` U2 ON F1.following_id = U2.id AND U2.is_active = 1

WHERE accounts_friend.accepted = 1 AND accounts_friend.deleted_at IS NULL AND accounts_friend.user_id != accounts_friend.following_id

这是我所做的,但肯定还没有完成

users = Friend.objects.filter(
    Q(user=request.user) & Q(accepted=True) & Q(deleted_at__isnull=True) & Q(following__is_active=True) & ~Q(following=request.user)
).annotate(
    username=F('following__friend__following__username')
).values('username')

如果有不清楚的地方,请告诉我以补充更多细节。

【问题讨论】:

  • 您想获取所有关注另一个用户的用户吗?您是否考虑过使用ManyToManyField 使用Friend 模型作为直通表?

标签: django django-models django-orm


【解决方案1】:

您可以查询此类User 对象:

User.objects.filter(
    ~Q(friend__user_id=F('pk')),
    ~Q(friend__user__friend__user_id=F('friend__user_id')),
    is_active=True,
    friend__accepted=True,
    friend__deleted_at=None,
    friend__user__is_active=True,
    friend__user__friend__accepted=True,
    friend__user__friend__deleted_at=None,
    friend__user__friend__user=request.user
)

查询模型对象通常比查询数据库值更好。由于模型对象“更丰富”:它们具有定义的行为,并且可以轻松传递以执行处理。

【讨论】:

    【解决方案2】:

    以下查询应为您提供所有 Users 后跟 user

    User.objects.filter(
        is_active=True,
        friend__user=request.user,
        friend__accepted=True,
        friend__deleted_at__isnull=True
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-15
      • 1970-01-01
      • 1970-01-01
      • 2021-09-26
      相关资源
      最近更新 更多