django视图中的无限循环



我一直在思考为什么不返回PrivateMessage列表。有时一双不同的眼睛可以立刻发现它,所以我在这里发布这篇文章,希望有人能发现错误。

这是一个函数,它可以获得20条或更少的私人消息,并删除同一用户的重复消息,也就是说,在返回的一批pm中,每个用户只有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个pm才具有的welcome设置了一个例外。

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多个下午,但当我试图检索前20个下午时,我得到的似乎是一个无限循环。它适用于其他用户,但第一个用户中pm的排序方式导致了错误。

如对此有任何见解,不胜感激。

我认为您的中断条件无效:

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循环的最后一部分有副作用。请考虑重写代码以使其更清晰。

事实证明,同一用户的pm在一行中太多了,所以当它试图获取n条私人消息时,它从未达到20条。我添加了一个函数来创建bl中所有用户的列表,并在查询中排除了他们。谢谢你的回复。

最新更新