python - Django 管理命令不刷新标准输出
问题描述
我正在尝试在 Django 管理命令中处理需要一段时间的处理前后打印到控制台,如下所示:
import requests
import xmltodict
from django.core.management.base import BaseCommand
def get_all_routes():
url = 'http://busopen.jeju.go.kr/OpenAPI/service/bis/Bus'
r = requests.get(url)
data = xmltodict.parse(r.content)
return data['response']['body']['items']['item']
class Command(BaseCommand):
help = 'Updates the database via Bus Info API'
def handle(self, *args, **options):
self.stdout.write('Saving routes ... ', ending='')
for route in get_all_routes():
route_obj = Route(
route_type=route['routeTp'], route_id=route['routeId'], route_number=route['routeNum'])
route_obj.save()
self.stdout.write('done.')
在上面的代码中,Saving routes ...
预计在循环开始之前done.
打印,并在循环完成时打印在它旁边,这样它看起来就像Saving routes ... done.
在结束时一样。
但是,前者在循环完成之前不会打印,当两个字符串最终同时打印时,这不是我所期望的。
我发现了这个问题,答案建议刷新输出 ie self.stdout.flush()
,所以我将它添加到我的代码中:
def handle(self, *args, **options):
self.stdout.write('Saving routes ... ', ending='')
self.stdout.flush()
for route in get_all_routes():
route_obj = Route(
route_type=route['routeTp'], route_id=route['routeId'], route_number=route['routeNum'])
route_obj.save()
self.stdout.write('done.')
尽管如此,结果仍然没有改变。
我做错了什么?
解决方案
要记住的是您正在使用 self.stdout(如 Django 文档中所建议的那样),它是 BaseCommand 对 Python 标准 sys.stdout 的覆盖。与您的问题相关的两者之间有两个主要区别:
- BaseCommand 的 self.stdout.write() 版本中的默认“结尾”是换行符,迫使您使用结尾=''参数,这与默认为空结尾的 sys.stdout.write() 不同。这本身不会导致您的问题。
- Flush() 的 BaseCommand 版本实际上并没有做任何事情(谁会想到?)。这是一个已知的错误:https ://code.djangoproject.com/ticket/29533
所以你真的有两个选择:
- 不使用 BaseCommand 的 self.stdout,而是使用 sys.stdout,在这种情况下,刷新确实有效
- 通过将“-u”参数传递给 python,在运行管理命令时强制标准输出完全无缓冲。所以不是运行
python manage.py <subcommand>
,而是运行python -u manage.py <subcommand>
希望这可以帮助。
推荐阅读
- javascript - 如何在中间件中将 Koa bodyParser 上传限制设置为特定路由而不是全局?
- javascript - 在cropper js中上传图片会出错拒绝加载图片违反内容安全策略指令:“img-src * data:”
- kubernetes - 无法访问用完 istio 服务网格的 api
- angular - 如何将授权标头设置为为其他 API 请求生成的不记名令牌
- javascript - 更改 Google 饼图上的饼图文本
- html - 为什么这个引导模板有一个从左到右的滚动条?
- javascript - GoogleJsonResponseException:对 drive.files.insert 的 API 调用因内部错误而失败
- r - 使用 Rvest 进行网页抓取,UseMethod(“xml_find_first”)中的错误:没有适用于“字符”类对象的“xml_find_first”方法
- cookies - 如何使 Shopware 5 csrf 和 cookie 在 iframe 中工作?
- javascript - 新事件没有上一个事件更新的最新状态值