2013-05-11 3 views
6

나는 이런 식으로 뭔가를 보이는 장고 모델이의 값을 비교 4. 코더 3과 코더 4 사이의 값의 차이가 1보다 큰 모든 응답 객체의 목록을 얻으려고합니다. 값 필드에는 1-7이 저장됩니다.장고는 두 개의 객체

CharField로 값을 설정하는 것이 실수 일 수 있지만, 그럴 수 있으면 좋겠다.

나는 다음과 같은 SQL과 같은 뭔가 내가 무엇을 찾고 할 것이라고 생각하지만, 쿼리에 이미 테이블에 가입하면 차라리 ORM

SELECT UNIQUE c1.response_id FROM coding c1, coding c2 
WHERE c1.coder_id = 3 AND 
     c2.coder_id = 4 AND 
     c1.qid = "risk" AND 
     c2.qid = "risk" AND 
     c1.response_id = c2.response_id AND 
     c1.value - c2.value > 1 
+1

나는 당신이 당신의 쿼리의 WHERE 절에'c1.response_id = c2.response_id'을 포함하는 의미라고 생각한다. –

+0

@AryehLeibTaurog 예 했어요. 감사. – Ryan

답변

2
from django.db.models import F 
qset = Coding.objects.filter(response__coding__value__gt=F('value') + 1, 
          qid='risk', coder=4 
        ).extra(where=['T3.qid = %s', 'T3.coder_id = %s'], 
          params=['risk', 3]) 
responses = [c.response for c in qset.select_related('response')] 

이 할 것 ORM은 두 번째 매개 변수에 extra()을 사용할 수있는 별칭 (이 경우 T3)을 할당합니다. 별칭이 무엇인지 알아 내기 위해 쉘에 넣을 수 있으며 print qset.query입니다.

참조 장고 F objects에 문서와 extra

업데이트 : 때마다 당신이 당신 조회에 response__coding을 참조하기 때문에 실제로, extra()를 사용하거나 별칭 사용을 장고 알아낼 필요가 없습니다 것 같다, django는 처음에 생성 된 별칭을 사용합니다. 다음은 어느 방향의 차이를 찾는 하나 개의 방법 : BTW Q objects

from django.db.models import Q, F 
gt = Q(response__coding__value__gt=F('value') + 1) 
lt = Q(response__coding__value__lt=F('value') - 1) 
match = Q(response__coding__qid='risk', response__coding__coder=4) 
qset = Coding.objects.filter(match & (gt | lt), qid='risk', coder=3) 
responses = [c.response for c in qset.select_related('response')] 

참조 장고 문서는 모두 코딩 인스턴스를 원하는 위하여려고하는 경우에, 당신은, 때문에 여기에 N + 1 개 쿼리 문제가 django의 select_related()은 역방향 FK 관계를 가져 오지 않습니다. 그러나 쿼리의 데이터가 이미 있으므로 위에 설명 된 T3 별칭과 extra(select={'other_value':'T3.value'})을 사용하여 필요한 정보를 검색 할 수 있습니다. 해당 코딩 레코드의 value 데이터는 검색된 코딩 인스턴스의 속성, 즉 c.other_value으로 액세스 할 수 있습니다.

덧붙여서 질문은 일반적으로 충분하지만 RDB 시나리오에서 일반적으로 반 패턴으로 간주되는 엔티티 속성 값 스키마가있는 것처럼 보입니다. risk 필드 당신은 더 나을 장기 수 있습니다 (이 쿼리는 간단 할 것) :

class Coding(models.Model): 
    response = models.ForeignKey(Response) 
    coder = models.ForeignKey(User) 
    risk = models.IntegerField() 
    # other fields for other qid 'attribute' names... 
+0

이것은 아주 좋습니다. 상관없이 코더 3 또는 코더 4 여부에 상관없이 작동하게하는 방법이 있습니까? – Ryan

+2

두 경우에 모두 적용되는 솔루션으로 답변을 업데이트했습니다. –