Python django视图中的无限循环
我一直在想我为什么不返回私人信息列表。有时,一双不同的眼睛可以立刻发现它,所以我在这里发布这篇文章,希望有人能发现错误 这是一个函数,它可以获取20条或更少的私人消息,并删除同一用户的重复消息,也就是说,在返回的pm批中,每个用户只有1条消息 它还排除了静默列表中的用户。这些都工作得很好,所以我不认为这与沉默有关 在调用remove\u duplicate\u users之后,我获得最后一个对象的id,以便在下一次查询中使用它 我冲洗并重复,直到列表中有20个对象准备返回,或者查询什么也不返回Python django视图中的无限循环,python,django,Python,Django,我一直在想我为什么不返回私人信息列表。有时,一双不同的眼睛可以立刻发现它,所以我在这里发布这篇文章,希望有人能发现错误 这是一个函数,它可以获取20条或更少的私人消息,并删除同一用户的重复消息,也就是说,在返回的pm批中,每个用户只有1条消息 它还排除了静默列表中的用户。这些都工作得很好,所以我不认为这与沉默有关 在调用remove\u duplicate\u 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循环的最后一部分是带有副作用的位。并且请考虑改写代码以使其更加清晰。< P>这是因为同一用户的PM太多,所以当它试图获取N个私人消息时,它永远达不到20。我添加了一个函数来创建bl中所有用户的列表,并在查询中排除了这些用户。感谢您的回复。第二位代码中的循环有些奇怪:您在循环中向
l
添加内容,然后仍然在循环中通过l
本身。这是对的,还是缩进问题?对不起,我把第一个函数复制错了,我现在已经修复了。啊,变量名的这种深奥用法。我在这里看到了一些不一致,返回Httpresponse(pms)
(其中定义了pms)和sender\u in=[s.breakt for s in ss]
,sender\u in=[s.brat for s in ss]
(相信应该是一样的)。你写的函数没有任何无限循环的副作用,我可以告诉你这么多。你写的是关于s.breakt第一部分的东西出了问题,应该是brat。是的,当pms被声明时,我删除了这行,我的错,这是为了避免引用与问题无关的另一个函数。我会解决这些问题。我希望收到前20条或更少的消息(如果数量更少)。所以n从20开始,减少到20-len(bl),也就是20减去已经在大列表中的消息。因此,我检查len(bl)是否已经是20(如果发生了任何奇怪的事情,则会超过20),或者查询是否不再返回任何内容(而不是pmr)。你关于n>=0的建议从一开始就是正确的。另一种方法是,如果有40条消息,检查-20>=0
,这是错误的,并且不会中断。如果您有16条消息,即4>=0
,则会中断。在任何一种情况下,关于代码的行为,我的推理可能有点错误,但肯定是你的中断条件有点不合适。如果我只有16条消息,首先可能会被remove_duplicate_用户删除其中一些消息,然后让我们假设我只剩下7条消息。n将变为13,last_pm_id将成为大列表中最后一条消息的id,比如234。在这种情况下,由于bl不>=20且pmr不为空,因此这两个参数都将失败。然后在下一次迭代中,它将搜索id低于上一次的pm,并返回空。bl将保持不变。它将失败bl>=20,但pmr将为false,那么它应该通过。我删除了\u重复的\u用户循环很好地中断了,所以问题就出现了。。