2009-03-04 35 views
1

是否有使用Django的QuerySet對象改寫這個查詢方式:自我的Django 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是日期時間。

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"] 

聚集僅在後備箱,所以你可能需要更新你的Django安裝,你可以做到這一點之前。

+0

你可能是最接近的可能性 - 但正如你所說,效率低下。 我決定直接使用.extra()執行sql。 – 2009-03-05 21:00:55

0

聚合不是問題;這裏的問題是Django的ORM根本不會連接任何不是ForeignKey AFAIK的東西。

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