2017-12-26 17 views
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 및 피어 하나 Beetween 하나의 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 U1.stopped = FALSE) 
); 

ORM이나와 그것을 달성 할 수있는 방법이 있나요 : 내가 생각하고 있었는데 (무엇 예상 결과를 제공하는 것은) 같은 일이

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) 
); 

입니다 원시 SQL을 사용해야한다. 나는 주석에 대해서도 생각하고 있었지만, 아직 방법을 구현하는 방법을 100 % 확신하지는 못했다.

답변

0

나는 해결책을 생각해 냈습니다. 아마도 가장 최적의 변형을

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); 

을하지하지만 적어도 하나 개의 요청에서 작동 : 이런 식 결과

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() 

. 더 좋은 방법이 있으면 알려주세요.