Django:在上下文中传递模型后更改模型
查看时我正在更改字段值列表,但我希望将未更改的值传递给上下文。这里的情况是原始通知系统,在查看通知时,它应将其状态更改为“已查看” views.pyDjango:在上下文中传递模型后更改模型,django,Django,查看时我正在更改字段值列表,但我希望将未更改的值传递给上下文。这里的情况是原始通知系统,在查看通知时,它应将其状态更改为“已查看” views.py class Notification(TemplateView): template_name='myapp/notification.html' def get_context_data(self, **kwargs): user = self.request.user user_unread = user.notificat
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>
未读:
{用户中的msg为%u未读%}
- {{msg}}
{%endfor%}
已阅读:
{用户_read%}中的msg为%
- {{msg}}
{%endfor%}
另一方面,我是CBV新手,如果上面的视图代码可以改进的话,我希望有一些指针。这是由于查询集的惰性。查询集在您对数据库求值之前不会实际接触数据库,这通常发生在您迭代时。因此,在您的代码中,您迭代视图中的
user\u unread
,以设置读取状态:因此查询集的内容在该点是固定的。但是,在到达模板之前,您不会遍历user\u read
,因此在更新所有未读通知之前,不会进行查询
解决此问题的方法是在更新未读查询集之前,在视图中显式计算已读查询集。您只需在其上调用list
即可:
context.update({'user_unread': user_unread, 'user_read': list(user_read)})
for msg in user_unread:
...
您可以尝试获取另一个重复查询集以更新对象。使用未更新的模板上下文,并仅更新另一个模板上下文 比如: Django会对每个查询集进行不同的缓存。因此,一旦评估
用户\u未读
将拥有自己的对象副本
虽然,由于加载了类似查询集的多个副本,因此它不是非常优雅/高效,因此如果记录数太多,它将变慢。不,这将不起作用,原因完全相同:查询集在更新完成后才会计算,因此消息将始终显示为已读。@DanielRoseman,我已经提到了这一点,并且评估了QS
len(user\u unread)
,以便在获得它之后,对它进行评估。啊,对不起,没有看到这一点。
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