从查询集中排除查询集的最佳方法是什么

时间:2011-10-10 19:32:36

标签: python django

我正在编写收件箱视图,我想从看到的邮件中排除看不见的邮件。 我的代码是:

  

def render_notifications(request):

 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(recipient = request.user).exclude(id__in = unseen_messages)

修改

使用 unseen = False 时,我无法正确获取已见消息,因为我会在访问该网页时标记所有看不见的消息。出于一个奇怪的原因,当我在通知查询中使用unseen = False时,将从通知查询中检索所有标记的看不见的消息。

2 个答案:

答案 0 :(得分: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")

答案 1 :(得分:1)

Django querysets are lazy。这解释了当您遵循Derek建议上述评论时,“看不见”通知出现在所见通知列表中的原因。在调用render_to_response时呈现模板之前,不会执行通知查询。到这个时候你已经保存了msg。

如果您在查询集上调用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方法,而不是遍历每个通知。如果您的模型具有自定义保存方法,或者您使用书面的前/后保存挂钩,则无法执行此操作。