Django2.2.4+Python3.7调用values_list触发StopIteration临时修复咨询
临时解决Django 2.2.4 + Python 3.7下.values_list(flat=True)触发的StopIteration错误
针对你遇到的这个版本兼容bug,我整理了两个临时可行的解决思路,帮你先绕过问题:
方法一:临时修改Django源码(应急用)
找到你的虚拟环境里的django/db/models/base.py文件,定位到from_db方法中的这段代码:
values = [ next(values_iter) if f.attname in field_names else DEFERRED for f in cls._meta.concrete_fields ]
把它修改为给next()添加默认值,这样当迭代器耗尽时不会抛出StopIteration:
values = [ next(values_iter, DEFERRED) if f.attname in field_names else DEFERRED for f in cls._meta.concrete_fields ]
修改后重启服务,这个错误应该就不会再出现了。
方法二:绕过.values_list(flat=True)的写法
如果不想修改源码,可以换一种方式实现相同的效果,比如用.values()配合列表推导式:
# 原来的写法 MyModel.objects.values_list('myfield', flat=True) # 替换后的写法 [item['myfield'] for item in MyModel.objects.values('myfield')]
这种方式不会触发from_db里的问题逻辑,自然也就避开了这个bug。
补充说明
这个问题的根源是Django 2.2.4的from_db方法在处理字段数少于模型总字段的查询时,没有处理next(values_iter)可能触发的StopIteration异常——Python 3.7里迭代器耗尽时next()会直接抛出这个异常,而这段代码没有做捕获处理。官方后续应该会修复这个兼容问题,但在那之前,上面的两种方法可以帮你解决当前的问题。
内容的提问来源于stack exchange,提问作者M-N
相关产品推荐
相关产品推荐

