2011-10-10 74 views
1

我正在编写收件箱视图,并且希望从看到的消息中排除看不见的消息。 我的代码是:排除查询集中的查询集的最佳方式

高清render_notifications(请求):

unseen_notices = notification.Notice.objects.filter(recipient=request.user,unseen=True).order_by("-added") 
notices = notification.Notice.objects.filter(recipient=request.user).exclude(id__in = [i.id for i in unseen_notices]).order_by("-added") 

for msg in unseen_notices: 
    msg.unseen = False 
    msg.save() 

context = RequestContext(request,{'notices':notices, 
       'unseen_notices':unseen_notices}) 
return render_to_response('my_notifications.html',context_instance=context) 

正如你可以看到我排除使用for循环这似乎并不方便所有看不见的消息,我不当然,但这条线会导致性能问题?最后一点是没有办法,我可以替换类似的东西这条线的方式:

通知= notification.Notice.objects.filter(收件人= request.user).exclude(id__in = unseen_messages)

编辑:

我不能得到看到消息正确使用看不见=假,因为我标记所有看不见的消息被访问页面时所看到。出现奇怪的原因,当我在查询通知中使用unseen = False时,从通知查询中检索到所有未标记的消息。

+1

只是好奇,你可以不过滤'unseen = False'?即'notices = notification.Notice.objects.filter(receivingient = request.user,unseen = False)...' –

+0

如果我这样做了,那些看不见的消息将被标记为可见,并且不知道为什么,但它们在通知查询集。 – iva123

回答

1

Django querysets are lazy。这解释了为什么当您按照Derek的建议进行上述评论时,看不见的通知会出现在所看到的通知列表中。通知查询在执行render_to_response时呈现模板之前不会执行。到这个时候,你已经保存了所见的味精。

如果您在查询集上调用list(),则会立即对其进行评估,并且看不见的通知中将不再显示“未见”通知。

def render_notifications(request): 
    user_notices = notification.Notice.objects.filter(recipient=request.user).order_by(-'added') 
    unseen_notices = list(user_notices.filter(unseen=True)) 
    notices = list(user_notices.filter(unseen=False)) 
    <snip> 

另一种方法是使反应,然后在通知更新unseen标志,则最后返回的响应。

def render_notifications(request): 
    user_notices = notification.Notice.objects.filter(recipient=request.user).order_by(-'added') 
    unseen_notices = user_notices.filter(unseen=True) 
    notices = user_notices.filter(unseen=False) 

    context = RequestContext(request,{'notices':notices, 
      'unseen_notices':unseen_notices}) 
    response = render_to_response('my_notifications.html',context_instance=context) 

    # update the seen flag 
    unseen_notices.update(unseen=False) 

    return response 

请注意,我用的查询集,而不是通过每个通知循环的update方法。如果您的模型具有自定义保存方法,或者您正在使用写入的前/后保存钩子,则无法执行此操作。

1

似乎是你可以做这样的事情在这里:

user_notices = notification.Notice.objects.filter(recipient=request.user) 
unseen_notices = user_notices.filter(unseen=True).order_by("-added") 
notices = user_notices.exclude(unseen=True).order_by("-added") 
+0

+1设置'user_notices'可以避免重复收件人过滤器。你可以在'user_notices'查询集上放置'order_by'调用,使其甚至可以DRYer。 – Alasdair