过滤许多到很多字段Django

问题描述 投票:1回答:1

我有这样的查询:

    queryset = User.objects.filter(
            ~Q(pk=self.request.user.pk),
            ~Q(connections_as_initiator__peer=self.request.user, 
               connections_as_initiator__stopped=False))

在一个intitator和peer之间可能有许多连接bun只有一个不是stopped。所以我希望这个查询要做的是查找当前用户和查询者之间是否存在当前用户是对等体的活动连接。但这根本不是发生的事情:

SELECT accounts_user.id FROM accounts_user
WHERE (
  NOT accounts_user.id = 48
  AND NOT accounts_user.id IN (SELECT U1.initiator_id AS col1 FROM connection U1 WHERE U1.peer_id = 48)
      AND NOT accounts_user.id IN (SELECT U1.initiator_id AS col1 FROM connection U1 WHERE U1.stopped = FALSE)
);

我在想什么(以及给出预期结果的是什么)是这样的:

SELECT accounts_user.id FROM accounts_user
WHERE (
  NOT accounts_user.id = 48
  AND NOT accounts_user.id IN (SELECT U1.initiator_id AS col1 FROM connection U1 WHERE U1.peer_id = 48 AND U1.stopped = FALSE)
);

有没有办法用ORM实现,或者我应该开始使用原始SQL。我也在考虑注释,但我还不能100%确定如何以这种方式实现它。

sql django many-to-many django-orm
1个回答
0
投票

好像我想出了一个解决方案。

queryset.annotate(
            initiated_conn_with_usr=Case(
                When(
                    connections_as_initiator__peer=self.request.user, 
                    connections_as_initiator__stopped=False, 
                    then=True
                ), default=False, output_field=models.BooleanField()
            )
        ).filter(initiated_conn_with_usr=True).distinct()

结果是这样的:

SELECT DISTINCT accounts_user.id,
  CASE WHEN (connection.peer_id = 48 AND connection.stopped = false)
    THEN true ELSE false END AS initiated_conn_with_usr FROM accounts_user
  LEFT OUTER JOIN connection ON (accounts_user.id = connection.initiator_id)
WHERE (CASE WHEN (connection.peer_id = 48 AND connection.stopped = false)
  THEN true ELSE false END = false);

可能不是最佳的变体,但至少它可以在一个请求中工作。如果有更好的方法,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.