2009-03-04 2 views
1

가 장고 검색어 세트 객체를 사용하여이 쿼리를 다시 작성하는 방법이 조인장고 1.0/1.1 재 작성

SELECT b.created_on, SUM(a.vote) 
FROM votes a JOIN votes b ON a.created_on <= b.created_on 
WHERE a.object_id = 1 
GROUP BY 1 
이 투표가 테이블 인

, OBJECT_ID 여러 번 (외부 키를 발생하는 int입니다 - 그것은 여기서는 중요하지 않지만), 그리고 created_on은 datetime입니다.

FWIW,이 쿼리를 사용하면 이전에 해당 object_id의 모든 이전 투표 수를 합하여 과거의 점수를 얻을 수 있습니다.

답변

1

나는 Django ORM으로 쿼리를 생성 할 수 없다고 확신한다. 새로운 Django 집계 코드는 매우 유연하지만 원하는대로 정확히 수행 할 수 있다고는 생각하지 않습니다.

쿼리가 작동합니까? b.object_id가 1이라는 수표가 누락 된 것 같습니다.

이 코드는 작동하지만 한 줄 이상이 아니며 효율적이지 않습니다. 당신은이 작업을 수행 할 수 있습니다 전에 장고 설치 갱신 할 필요가있을 수 있으므로

from django.db.models import Sum 

v_list = votes.objects.filter(object__id=1) 

for v in v_list: 
    v.previous_score = votes.objects.filter(object__id=1, created_on__lte=v.created_on).aggregate(Sum('vote'))["vote__sum"] 

집계, 트렁크에서만 사용할 수 있습니다.

+0

당신의 의견은 아마도 가장 가까운 가능성 일 것입니다. .extra()를 사용하여 SQL을 직접 실행하기로 결정했습니다. –

0

집계가 문제되지 않습니다. 여기서 문제는 Django의 ORM이 AFAIK가 아닌 ForeignKey에 대한 조인을 수행하지 않는다는 것입니다.

0

이것은 내가 지금 사용하고있는 것입니다. 역설적이게도 SQL은 손상되었지만 이것의 요지는 다음과 같습니다.

def get_score_over_time(self, obj): 
    """ 
    Get a dictionary containing the score and number of votes 
    at all times historically 
    """ 
    import pdb; pdb.set_trace(); 
    ctype = ContentType.objects.get_for_model(obj) 
    try: 
     query = """SELECT b.created_on, SUM(a.vote) 
         FROM %s a JOIN %s b 
         ON a.created_on <= b.created_on 
         WHERE a.object_id = %s 
         AND a.content_type_id = %s 
         GROUP BY 1""" % (
      connection.ops.quote_name(self.model._meta.db_table), 
      connection.ops.quote_name(self.model._meta.db_table), 
      1, 
      ctype.id, 
      ) 
     cursor = connection.cursor() 
     cursor.execute(query) 
     result_list = [] 
     for row in cursor.fetchall(): 
      result_list.append(row) 
    except models.ObjectDoesNotExist: 
     result_list = None 
    return result_list