2016-05-08 36 views
2

我有一個Django應用程序,用戶上傳照片並在其下留下評論。反映這些對象的數據模型分別爲PhotoPhotoComment優化Django查詢集的相關比較

還有第三個數據模型叫做PhotoThreadSubscription。每當用戶在照片下評論時,用戶通過在PhotoThreadSubscription中創建對象來訂閱該特定線程。這樣,他/她隨後可以被其他用戶留在同一主題中的評論通知。

class PhotoThreadSubscription(models.Model): 
    viewer = models.ForeignKey(User) 
    viewed_at = models.DateTimeField(db_index=True) 
    which_photo = models.ForeignKey(Photo) 

每次下照片的用戶的意見,我更新用戶的PhotoThreadSubscription對象的該特定照片viewed_at屬性。 其他用戶對該特定線程的提交時間大於viewed_at的任何意見因此爲

假設我有一個註釋查詢集,全部屬於獨一無二的照片。我想遍歷這個查詢集並找到最新的看不見的評論

目前,我在一個非常沉重的DB方式嘗試這樣的:

latest_unseen_comment = PhotoComment(id=1) #i.e. a very old comment 
for comment in comments: 
    if comment.submitted_on > PhotoThreadSubscription.objects.get(viewer=user, which_photo_id=comment.which_photo_id).viewed_at and comment.submitted_on > latest_unseen_comment.submitted_on: 
     latest_unseen_comment = comment 

這顯然不是做一個好辦法。首先,我不想在for循環中執行DB調用。如何在一次通話中管理上述內容?具體來說,如何在一次調用中獲得相關的PhotoThreadSubscription查詢集,然後,如何使用它來計算max_unseen_comment?我現在非常困惑。


class Photo(models.Model): 
    owner = models.ForeignKey(User) 
    image_file = models.ImageField(upload_to=upload_photo_to_location, storage=OverwriteStorage()) 
    upload_time = models.DateTimeField(auto_now_add=True, db_index=True) 
    latest_comment = models.ForeignKey(blank=True, null=True, on_delete=models.CASCADE) 


class PhotoComment(models.Model): 
    which_photo = models.ForeignKey(Photo) 
    text = models.TextField(validators=[MaxLengthValidator(250)]) 
    submitted_by = models.ForeignKey(User) 
    submitted_on = models.DateTimeField(auto_now_add=True) 

請要求澄清,如果問題似乎朦朧。

回答

2

我認爲這將做它在一個單一的查詢:

latest_unseen_comment = (
    comments.filter(which_photo__photothreadsubscription__viewer=user, 
        which_photo__photothreadsubscription__viewed_at__lt=F("submitted_on")) 
      .order_by("-submitted_on") 
      .first() 
) 

使用F expressions,這樣的比較可以與每個評論的個人日期來完成,而不是使用一個單獨的日期這裏的關鍵在硬編碼查詢。在過濾查詢集以僅包含未見的評論之後,我們然後order_by評論的日期並採取第一個。