Django:在上下文中传递模型后更改模型

时间:2014-06-23 11:40:43

标签: 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>

在旁注中,我是CBV的新手,如果我的观察代码可以改进,我会喜欢一些指示。

2 个答案:

答案 0 :(得分:1)

这是由于查询集的惰性。在您评估之前,查询集实际上并不会触及数据库,这通常在您进行迭代时发生。因此,在您的代码中,您在视图中迭代user_unread,以设置读取状态:因此查询集的内容在该点处是固定的。但是,在您到达模板之前,您不会遍历user_read,因此在此之前不会进行查询,之后您已更新所有未读通知。

解决此问题的方法是在更新未读取的查询之前,在视图中显式评估读取查询集。您只需在其上调用list即可完成此操作:

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

答案 1 :(得分: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将拥有自己的对象副本。

虽然它不是很优雅/高效,因为加载了类似查询集的多个副本,所以如果记录数量很高,它会更慢。