0

我一直在试图弄清楚为什么我不返回 PrivateMessages 列表。有时另一双眼睛可以立即发现它,所以我在这里发布这个,希望有人发现错误。

这是一个获取 20 条或更少的私人消息并删除同一用户的重复消息的函数,即每个用户只有 1 条消息进入返回的一批下午。

它还排除了静音列表中的用户。这些一直运行良好,所以我认为这与 Silenced 位无关。

在调用 remove_duplicate_users 后,我得到最后一个对象的 id 以在下一个查询中使用它。

我冲洗并重复,直到我在列表中准备好返回 20 个对象或查询不返回任何内容。

def get_private_messages(request):
    ss = Silenced.objects.filter(user=request.user)
    last_pm_id = None
    n = 20
    bl = []
    while True:
        if last_pm_id:
            pmr = PrivateMessage.objects.filter(user=request.user,hidden=False,id__lt=last_pm_id).exclude(sender__in=[s.brat for s in ss]).order_by('-id')[:n]
        else:   
            pmr = PrivateMessage.objects.filter(user=request.user,hidden=False).exclude(sender__in=[s.brat for s in ss]).order_by('-id')[:n]
        l = list(pmr)
        bl = bl + l
        bl = remove_duplicate_senders(bl)
        n = 20 - len(bl)
        last_pm_id = bl[-1].id
        if len(bl) >= 20 or not pmr:
            break

    return HttpResponse(bl)

这是删除重复用户消息的功能。对于名为 pin 或 note 的用户,如果 pm.info1 与仅在前 10 点具有的欢迎匹配,则它会例外。

def remove_duplicate_senders(pmr):
    l = []
    a = False
    for p in pmr:
        a = True
        if p.sender.username in ['pin','note'] or p.info1=='welcome':
            l.append(p)
            continue
        for px in l:
            if p.sender.username == px.sender.username:
                a = False
                break
        if a:
            l.append(p)
    return l

我正在测试的用户有超过 60 pm,但是当我尝试检索前 20 pm 时,我得到了一个似乎是无限循环的东西。它适用于其他用户,但在第一个用户中订购 pm 的方式导致错误。

感谢您对此的任何见解,谢谢。

4

2 回答 2

0

我认为您的休息条件无效:

if len(bl) >= 20 or not pmr:
    # Stop if I have more than 20 messages? Shouldn't I continue filtering?
    break

应该:

if n >= 0:
    # Stop only if I have 20 or less [n = 20 - len(bl)], continue otherwise
    break

我可能误解了一些东西,但是你的 while 循环的最后一部分是有副作用的。请考虑重写代码以使其更易读。

于 2012-10-04T22:25:50.140 回答
0

原来是同一用户的 pm 太多连续出现的情况,所以当它尝试获取 n 条私信时,它从未达到 20。我添加了一个函数来创建所有用户的列表bl 并在查询中排除它们。感谢您的回复。

于 2012-10-05T03:29:39.950 回答