2014-06-23 124 views
0

我正在更改查看時字段值的列表,但我想將未更改的值傳遞給上下文。這裏的情況是一個原始通知系統,在查看通知後,它應該將其狀態更改爲查看。Django:在上下文中傳遞模型後更改模型

views.py

class Notification(TemplateView): 

template_name='myapp/notification.html' 

def get_context_data(self, **kwargs): 
    user = self.request.user 
    user_unread = user.notification_set.filter(viewed=False) 
    user_read = user.notification_set.filter(viewed=True) 
    context = super(Notification, self).get_context_data(**kwargs) 
    context.update({'user_unread': user_unread, 'user_read': user_read}) 
    for msg in user_unread: 
     msg.viewed = True 
     msg.save() 
    return context 

然而與此代碼的問題是,我得到重複值在讀和未讀名單,即使我已經更新了上下文之後保存到模型中的新值傳遞給模板。

模板:

Unread: 
<ul> 
{% for msg in user_unread %} 
    <li> {{ msg }} </li> 
{% endfor %} 
</ul> 

Already read: 

<ul> 
{% for msg in user_read %} 
    <li> {{ msg }} </li> 
{% endfor %} 
</ul> 

在一個旁註,我是新來的CBVS,如果有,如果我認爲上面的代碼可以改善我喜歡一些指點。

回答

1

這是由於查詢集的惰性。查詢集在評估數據庫之前並不實際觸及數據庫,這通常會在迭代時發生。因此,在您的代碼中,您在視圖中遍歷user_unread,以設置讀取狀態:因此查詢集的內容在該點處固定。但是您不會遍歷user_read,直到您到達模板,因此直到之後,纔會更新所有未讀通知。

解決此問題的方法是在更新未讀取之前顯式評估視圖中的讀取查詢集。你可以通過簡單地調用它list做到這一點:

context.update({'user_unread': user_unread, 'user_read': list(user_read)}) 
for msg in user_unread: 
    ... 
1

你可以嘗試讓其他重複查詢要更新的對象。使用未更新的模板上下文並僅更新另一個模板上下文。

像:

def get_context_data(self, **kwargs): 
    user = self.request.user 
    user_unread = user.notification_set.filter(viewed=False) 

    #Do some operation on qs so that it gets evaluated, like 
    nitems = len(user_unread) 

    #get another queryset to update 
    user_unread_toupdate = user.notification_set.filter(viewed=False) 

    user_read = user.notification_set.filter(viewed=True) 
    context = super(Notification, self).get_context_data(**kwargs) 
    context.update({'user_unread': user_unread, 'user_read': user_read}) 

    #Use 2nd queryset 
    for msg in user_unread_toupdate: 
     msg.viewed = True 
     msg.save() 
    return context 

Django的將緩存每個查詢集不同。所以一旦評估user_unread將擁有自己的對象副本。

儘管它不像加載類似查詢集的多個副本那樣非常優雅/高效,所以如果記錄數很高,它會變慢。

+0

不,這是行不通的,原因完全一樣:查詢集在更新完成後才進行評估,因此這些消息總是顯示爲已讀。 –

+0

@DanielRoseman,已經提到並評估了QS'len(user_unread)',以便在得到它之後進行評估。 – Rohan

+0

啊,對不起,沒有看到。 –