bigywater.tech
Django · 25

runserver 自动重载机制

改了一行代码,runserver 是怎么知道的?是全盘监听吗?改模板要不要重启?这篇启动真实的 runserver,改文件、计时、数进程,把重载的边界摸清。

StatReloader
本机默认用轮询 stat 的重载器(输出:Watching for file changes with StatReloader)
0.2–0.8 s
修改被导入的 .py 到新代码生效的用时(3 次),期间进程被重启
模板不重启
改模板只重置模板缓存,不重启进程

用的是哪种 reloader

实测 · 本机执行输出
   Watching for file changes with StatReloader
   Performing system checks...
   
   System check identified no issues (0 silenced).
   
   You have 2 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): contenttypes.
   Run 'python manage.py migrate' to apply them.
   September 30, 2026 - 07:06:21
   Django version 6.1.1, using settings 'proj.settings'
   Starting WSGI development server at http://127.0.0.1:9330/
   Quit the server with CONTROL-C.
   

本机没有安装 pywatchman,所以用的是 StatReloader:定期检查已知文件的修改时间。(装了 watchman 后是否自动换用没有测。)

改 .py 文件

实测 · 本机执行输出
  改视图模块 lab/views.py                 生效用时(s):[0.23, 0.76, 0.8];期间新增的进程数:[1, 1, 1]

重载器发现被监视的文件变化后,让子进程退出、由父进程拉起新的子进程——所以每次改动进程 id 都变、ready() 重新执行(第 14 篇)。

改模板与其它文件

实测 · 本机执行输出
  改模板 templates/page.html(每次先请求一次让它进缓存)生效用时(s): [0.06, 0.53, 0.53]  期间读到旧内容的次数: [2, 18, 19]  新增进程: [0, 0, 0]
  改「没有被任何模块导入」的 lab/other.py 后 3 s 内新增进程 0 个
  改 notes.txt 后 3 s 内新增进程 0 个

被监视的是「已导入模块的文件 + 注册的额外路径(如模板目录)」。改一个没有被导入的 .py 或一个文本文件,不会有反应。改模板时 Django 只重置模板加载器的缓存。

分步演示:重载的边界

runserver 自动重载
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / Python 3.14.7 / Django 6.1.1(默认用 SQLite,其它数据库会在文中注明),用 django.test.Client 或真实的本机服务器进程实测;计时用 time.perf_counter,数字每次运行会有小幅抖动。每种改动重复 3 次;生效用时是「写文件」到「请求返回新内容」的时间,轮询间隔 20 ms
    • 没有验证:WatchmanReloader、大项目里 StatReloader 的 CPU 占用与轮询间隔、改 settings.py 的重启行为、新增文件(未被导入)后 import 它的情形、在 Docker 卷或网络文件系统上的 mtime 精度问题
    京ICP备2026067502号-1京公网安备11010502063487号