You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在后台线程中运行Django runserver以优化测试效率?

需求与问题

我需要在后台运行Django的runserver,配合selenium和pytest开展自动化测试。pytest-django提供的live_server虽有类似功能,但它会在每次测试后清空数据库——这意味着每次测试都要重新创建表、执行迁移,冗余且速度慢到无法接受。

我的核心目标是:只创建一次数据库和测试用户,用selenium登录后运行所有测试,但live_server显然无法实现这点。根据官方文档:

你需要在每次测试开始时重新填充数据库,因为测试之间数据库会被清空

官方没有给出解决方案,于是我转而尝试自行在后台启动Django服务器,试过几种方法但都遇到问题:


方法1:使用线程启动

我编写了如下代码:

import os
from pathlib import Path
from threading import Thread

from django.core.management import call_command
from django.core.wsgi import get_wsgi_application


def start_server(src):
    os.chdir(src)
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', f'{Path(src).name}.settings')
    os.environ['DB_NAME'] = 'test_db.sqlite3'
    get_wsgi_application()
    call_command('migrate')
    call_command('runserver')


def run_server(src):
    thread = Thread(target=start_server, args=[src], daemon=True)
    thread.start()


if __name__ == '__main__':
    run_server('/path/to/myproject-root')

但运行时抛出错误:

Traceback (most recent call last):
  File "/usr/local/Cellar/python@3.11/3.11.2_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/threading.py", line 975, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/user/Library/Application Support/JetBrains/PyCharm2022.3/scratches/scratch_3.py", line 15, in start_server
    call_command('runserver')
  File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 198, in call_command
    return command.execute(*args, **defaults)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/core/management/commands/runserver.py", line 74, in execute
    super().execute(*args, **options)
  File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 448, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/core/management/commands/runserver.py", line 111, in handle
    self.run(**options)
  File "/usr/local/lib/python3.11/site-packages/django/core/management/commands/runserver.py", line 118, in run
    autoreload.run_with_reloader(self.inner_run, **options)
  File "/usr/local/lib/python3.11/site-packages/django/utils/autoreload.py", line 673, in run_with_reloader
    signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))
  File "/usr/local/Cellar/python@3.11/3.11.2_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/signal.py", line 56, in signal
    handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: signal only works in main thread of the main interpreter

方法2:改用进程启动

我把线程替换为进程:

process = Process(target=start_server, args=[src], daemon=True)

但发现必须移除daemon=True才能正常运行,可移除后无法在不关闭IDE的情况下终止进程,操作非常不便。


临时尝试:关闭自动重载

回到线程方案,修改call_command为:

call_command('runserver', use_reloader=False)

这次服务器能成功启动,但访问时会返回400错误响应。


内容的提问来源于stack exchange,提问作者nlblack323

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:33:23