报错
Watching for file changes with StatReloader
Traceback (most recent call last):
File "/dc_pywebs/genebank_be/manage.py", line 80, in <module>
main()
File "/dc_pywebs/genebank_be/manage.py", line 75, in main
execute_from_command_line(sys.argv)
File "/dc_pywebs/genebank_be/venv/lib/python3.10/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
utility.execute()
File "/dc_pywebs/genebank_be/venv/lib/python3.10/site-packages/django/core/management/__init__.py", line 413, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/dc_pywebs/genebank_be/venv/lib/python3.10/site-packages/django/core/management/base.py", line 354, in run_from_argv
self.execute(*args, **cmd_options)
File "/dc_pywebs/genebank_be/venv/lib/python3.10/site-packages/django/core/management/commands/runserver.py", line 61, in execute
super().execute(*args, **options)
File "/dc_pywebs/genebank_be/venv/lib/python3.10/site-packages/django/core/management/base.py", line 398, in execute
output = self.handle(*args, **options)
File "/dc_pywebs/genebank_be/venv/lib/python3.10/site-packages/django/core/management/commands/runserver.py", line 96, in handle
self.run(**options)
File "/dc_pywebs/genebank_be/venv/lib/python3.10/site-packages/django/core/management/commands/runserver.py", line 103, in run
autoreload.run_with_reloader(self.inner_run, **options)
File "/dc_pywebs/genebank_be/venv/lib/python3.10/site-packages/django/utils/autoreload.py", line 638, in run_with_reloader
start_django(reloader, main_func, *args, **kwargs)
File "/dc_pywebs/genebank_be/venv/lib/python3.10/site-packages/django/utils/autoreload.py", line 614, in start_django
ensure_echo_on()
File "/dc_pywebs/genebank_be/venv/lib/python3.10/site-packages/django/utils/autoreload.py", line 95, in ensure_echo_on
if not termios or not sys.stdin.isatty():
AttributeError: 'NoneType' object has no attribute 'isatty'
这个错误是由于 Django 的自动重载机制尝试访问 stdin
时失败,通常出现在容器或非交互式终端中运行 runserver
时。
具体错误:
AttributeError: 'NoneType' object has no attribute 'isatty'
这是因为 sys.stdin
为 None
,导致 isatty()
无法调用。
解决方案
方法一:禁用自动重载器(推荐容器中使用)
在 runserver
命令后加 --noreload
:
python manage.py runserver 0.0.0.0:9559 --noreload
或者在 docker-compose.yml
中添加一个 command
字段来覆盖入口命令:
command: python manage.py runserver 0.0.0.0:9559 --noreload
方法二:使用 watchgod
重载(Django 3.1+)
如果你使用的是 Django 3.1 或更新版本,可以改用 --reload
:
python manage.py runserver 0.0.0.0:9559 --reload
补充建议
如果你希望开发时也能热重载文件变化,建议使用 docker-compose
启动容器,并在本地挂载代码目录(你已经这么做了),然后加上 --noreload
让错误消失。
是的,你的直觉没错——stdin_open: true
和 tty: true
确实与是否提供“伪终端”相关,但它们不能解决你遇到的这个特定问题。
原因说明:
Django 的 autoreload
机制在某些环境下会尝试访问 sys.stdin
, 而在 Docker 中,即使 stdin_open: true
和 tty: true
设置了,也不能保证 sys.stdin
是可用的 TTY(有时是 None
),尤其当你是通过 docker-compose up
非交互方式运行时。
这是为什么你看到报错:
AttributeError: 'NoneType' object has no attribute 'isatty'
即使你设置了 stdin_open: true
和 tty: true
。
推荐做法
最可靠的解决方法仍然是 禁用 Django 自动重载器,即在 docker-compose.yml
中加入:
command: python manage.py runserver 0.0.0.0:9559 --noreload
这样可以避开终端交互问题。
总结
stdin_open
和tty
是必要的,如果你希望容器可交互(如运行 bash 时)。- 但它们不足以解决 Django autoreload 访问 stdin 的问题。
- 使用
--noreload
是推荐方案。