Cookiecutter Django 本地开发环境搭建完全指南:从裸机同步开发到异步任务与前端流水线
2026/9/15 6:12:52 网站建设 项目流程

Cookiecutter Django 本地开发环境搭建完全指南:从裸机同步开发到异步任务与前端流水线

【免费下载链接】cookiecutter-djangoCookiecutter Django is a framework for jumpstarting production-ready Django projects quickly.项目地址: https://gitcode.com/GitHub_Trending/co/cookiecutter-django

本篇指南以 Cookiecutter Django 项目的 docs/2-local-development/developing-locally.rst 文档为核心,系统讲解在不使用 Docker的前提下,如何在本地裸机(bare-metal)环境搭建并运行一个由 Cookiecutter Django 模板生成的 Django 项目。内容包括开发环境前置依赖、项目初始化与uv依赖管理、PostgreSQL 数据库创建与迁移、同步/异步两种开发服务器启动方式、双层项目结构下创建 Django App 的规范流程、本地邮件捕获方案(Mailpit / Mailtrap Local / Console)、Celery 异步任务调试,以及 Webpack/Gulp 前端流水线的使用。读完本文,你将掌握一套完整、可复现的本地开发工作流,并能理解每个步骤背后对应的源码实现。

前置依赖:裸机本地开发需要准备什么

与 Docker 方案不同,裸机(bare-metal)本地开发要求所有服务直接运行在你的宿主机上。根据原文档,在开始之前需要在宿主机上安装以下工具:

依赖用途获取方式
uvPython 包管理与虚拟环境工具(本项目依赖管理与运行命令的统一入口)官方安装文档(见原文档链接)
PostgreSQL项目默认数据库官方下载页
Redis仅当使用 Celery 异步任务时需要,作为任务队列 Broker官方下载页
Cookiecutter用于从模板生成新项目官方仓库

从模板生成项目是这一切的前提。生成命令定义在 docs/2-local-development/generate-project-block.rst 中:

cookiecutter gh:cookiecutter/cookiecutter-django

生成过程中会交互式询问一系列配置选项(如project_sluguse_dockeruse_celeryfrontend_pipelinemail_catcher等),完整选项说明可参考 docs/1-getting-started/project-generation-options.rst。在 setup 阶段输入的project_slug会作为后续所有命令中项目目录、数据库名、容器名等标识的基础。

注意:本指南对应的文档面向不使用 Docker的裸机场景。若你选择在初始化时设置use_docker = y,请参阅 docs/2-local-development/developing-locally-docker.rst,两者的环境变量与启动方式完全不同。

第一步:同步依赖并安装 pre-commit 钩子

项目生成完成后,进入项目目录并执行依赖安装:

cd <what you have entered as the project_slug at setup stage> uv sync git init # A git repo is required for pre-commit to install uv run pre-commit install

三个命令各有明确的职责:

  • uv sync:基于项目根目录的 pyproject.toml 和uv.lock锁文件,创建虚拟环境并安装全部开发依赖。由于模板默认生成uv.lock锁文件,uv sync会保证依赖版本的可复现性。
  • git init:正如原文档注释强调的,pre-commit的安装必须在一个 Git 仓库中进行。pre-commit 钩子依赖 Git 来检测暂存文件并执行 lint / 格式化检查。
  • uv run pre-commit install:在.git/hooks/中注册 pre-commit 钩子。原文档特别指出,pre-commit钩子在生成的项目中是默认存在的(pyproject.toml中会声明 pre-commit 相关配置),每次git commit时它会自动运行项目配置的 linter(如 ruff、black 风格检查等)。若跳过这一步,后续提交时会出现大量 CI 和 Linter 错误。

第二步:创建 PostgreSQL 数据库并配置环境变量

创建数据库

使用 PostgreSQL 自带的createdb工具创建数据库,数据库名与 setup 阶段输入的project_slug保持一致:

createdb --username=postgres <project_slug>

原文档特别提醒:如果这是你机器上第一次创建数据库,可能需要进行PostgreSQL 初始配置——即修改pg_hba.conf等配置文件,允许本地连接并为postgres用户设置密码。这是常见的初装坑:createdb连接失败时,优先检查本机 PostgreSQL 的认证方式(trust/md5/scram-sha-256)与postgres用户的密码是否已设置。

导出环境变量

export POSTGRES_USER=postgres export POSTGRES_PASSWORD= export POSTGRES_DB=<DB name given to createdb>

这些环境变量会被 config/settings/base.py 中的数据库配置读取。从源码可以看到:

if os.getenv("DATABASE_URL", default=None): DATABASES = {"default": env.db("DATABASE_URL")} # ... "HOST": env.str("POSTGRES_HOST", default="postgres"),

也就是说,裸机模式下如果不显式设置DATABASE_URL,则默认通过POSTGRES_HOST(非 Docker 场景默认值实际为localhost)、POSTGRES_PORTPOSTGRES_DBPOSTGRES_USERPOSTGRES_PASSWORD等变量拼装连接信息。裸机开发时必须把POSTGRES_HOST指向localhost,这与 Docker 场景下指向postgres服务名截然不同。

完整的可用环境变量清单(DJANGO_DEBUGDJANGO_SECRET_KEYDJANGO_ALLOWED_HOSTS等)可查阅 docs/1-getting-started/settings.rst,其中整理了各变量在开发环境与生产环境的默认值对照表。

环境变量的两种管理方式

原文档提供了两种推荐实践,避免每次打开终端都手动export

  1. .env文件 +DJANGO_READ_DOT_ENV_FILE=True:在项目根目录创建.env文件,定义全部所需变量;然后在宿主机设置DJANGO_READ_DOT_ENV_FILE=Truebase.py中对应READ_DOT_ENV_FILE设置,开启后项目会读取根目录.env文件并自动加载其中的变量。
  2. 本地环境管理器:如direnv,进入项目目录时自动加载环境变量。

第三步:迁移数据库并启动开发服务器

应用迁移

uv run python manage.py migrate

manage.py位于项目根目录({{cookiecutter.project_slug}}/manage.py),模板默认将DJANGO_SETTINGS_MODULE指向config.settings.local。迁移会创建 Django 内置表以及users应用、contrib/sites应用的初始表结构。

启动服务器:同步 vs 异步

根据你的项目是否启用了异步支持,选择对应的启动方式。

同步(默认)——使用 Django 自带开发服务器:

uv run python manage.py runserver 0.0.0.0:8000

异步——使用 Uvicorn 运行 ASGI 应用(模板默认提供config.asgi:application,见 config/asgi.py):

uv run uvicorn config.asgi:application --host 0.0.0.0 --reload --reload-include '*.html'

--reload-include '*.html'保证了修改模板文件时也能触发热重载。如果项目选择了 Webpack 或 Gulp 作为前端流水线,则不要用上述命令直接访问 8000 端口,应改走 Webpack/Gulp 小节 的流程。

创建你的第一个 Django App:双层项目结构规范

原文档明确指出,该项目采用Two Scoops of Django一书推荐的双层布局(two-tier layout)

  • 顶层仓库根(Top Level Repository Root):存放配置文件、文档、manage.pyrequirements/README.md等;
  • 第二层 Django 项目根(Second Level Django Project Root):所有 Django App 的存放位置;
  • 第二层配置根(Second Level Configuration Root):即config/,存放 settings 与 URL 配置。

对应仓库中{{cookiecutter.project_slug}}/目录下的实际结构,其布局如下:

<repository_root>/ ├── config/ │ ├── settings/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── local.py │ │ └── production.py │ ├── urls.py │ └── wsgi.py ├── <django_project_root>/ │ ├── <name_of_the_app>/ │ │ ├── migrations/ │ │ ├── admin.py │ │ ├── apps.py │ │ ├── models.py │ │ ├── tests.py │ │ └── views.py │ ├── __init__.py │ └── ... ├── requirements/ │ ├── base.txt │ ├── local.txt │ └── production.txt ├── manage.py ├── README.md └── ...

说明:模板当前实际使用pyproject.toml+uv.lock作为依赖管理方案,requirements/*.txt是模板为兼容传统工作流保留的生成物;两者以pyproject.toml为主。

按此结构新增一个 App 的完整步骤:

# 1. 生成 App uv run python manage.py startapp <name-of-the-app> # 2. 移动到 Django 项目根,保持双层结构 mv <name-of-the-app> <django_project_root>/
# 3. 编辑 App 的 apps.py,修改 name 为带项目根的完整路径 name = '<django_project_root>.<name-of-the-app>'
# 4. 在 config/settings/base.py 的 LOCAL_APPS 列表中添加该 App LOCAL_APPS = [ # 你的新 App 名称(含项目根前缀) '<django_project_root>.<name-of-the-app>', ]

LOCAL_APPS定义在 config/settings/base.py 中,与DJANGO_APPSTHIRD_PARTY_APPS共同构成INSTALLED_APPS。注册后,App 便成为项目正式组成部分,可被迁移、Admin 和测试框架识别。

配置邮件后端:本地邮件捕获与测试

本地开发时,我们通常不想真正发送邮件,而是希望捕获并查看项目发送的邮件内容。典型场景是django-allauth在用户注册或重新验证时会发送验证邮件。原文档提供了三种方案,其中前两种依赖于项目初始化时的mail_catcher选项。

Mailpit(Go 编写的零依赖邮件捕获工具)

前提:项目初始化时mail_catcher必须设置为Mailpit

Mailpit 由 Go 编写,无外部依赖。安装步骤:

# 1. 下载对应系统的最新 release 二进制 # 2. 复制到项目根目录 # 3. 赋予可执行权限 chmod +x mailpit # 4. 另开一个终端窗口启动 ./mailpit # 5. 浏览器访问 Web 界面 http://127.0.0.1:8025/

在裸机模式下,local.py会为 Mailpit 配置如下(见 config/settings/local.py):

EMAIL_HOST = "localhost" EMAIL_PORT = 1025

即 Django 会把邮件发往本机 1025 端口的 Mailpit SMTP 服务,Mailpit 在 8025 端口提供 Web 界面查看邮件。

Mailtrap Local(MIT 许可的单文件 Go 二进制)

前提:项目初始化时mail_catcher必须设置为Mailtrap Local

# 1. 下载对应系统的最新 release 二进制 # 2. 复制到项目根目录 # 3. 赋予可执行权限 chmod +x mailtrap-local # 4. 另开一个终端窗口启动 ./mailtrap-local # 5. 浏览器访问 Web 界面 http://127.0.0.1:3550/

对应local.py的配置(见 config/settings/local.py):

EMAIL_HOST = "localhost" EMAIL_PORT = 3535

注意 Mailtrap Local 的 SMTP 端口(3535)与 Web 界面端口(3550)不同,而 Mailpit 两者都是 1025/8025。

Console 后端(默认兜底方案)

前提:项目初始化时mail_catcher设置为None(默认)。

此时local.py使用 Django 内置的 console 邮件后端(见 config/settings/local.py):

EMAIL_BACKEND = env( "DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.console.EmailBackend", )

邮件不会真正发送,而是直接打印到运行开发服务器的终端标准输出中。生产环境的邮件则由 Mailgun 等服务接管(相关配置见 docs/includes/mailgun.rst)。

Celery:本地异步任务的两种运行模式

如果项目初始化时启用了use_celery,默认情况下(非 Docker 裸机开发),local.py中会有如下设置(见 config/settings/local.py):

CELERY_TASK_ALWAYS_EAGER = True CELERY_TASK_EAGER_PROPAGATES = True

CELERY_TASK_ALWAYS_EAGER = True意味着任务不会进入 Broker 队列,而是在主线程同步执行,这样本地开发无需启动 Redis 与 worker 即可运行整个应用。这是裸机模式省心的默认行为。

切换为真实异步模式

如果你在本机安装了 Redis,希望在本地体验真实的异步任务队列,在config/settings/local.py中修改:

CELERY_TASK_ALWAYS_EAGER = False

然后分两个终端分别启动 Redis 与 Celery worker:

# 终端 1:启动 Redis redis-server # 终端 2:启动 Celery worker uv run celery -A config.celery_app worker --loglevel=info

这里的-A config.celery_app指向 config/celery_app.py。从源码可以看到,Celery 实例通过app.config_from_object("django.conf:settings", namespace="CELERY")从 Django settings 中读取所有CELERY_前缀配置,Broker 与结果后端在 config/settings/base.py 中定义:

REDIS_URL = env("REDIS_URL", default="redis://localhost:6379/0") CELERY_BROKER_URL = REDIS_URL CELERY_RESULT_BACKEND = REDIS_URL

裸机场景REDIS_URL默认指向localhost:6379。Celery worker 应在应用运行期间保持后台运行,以便及时消费队列中的任务。

用自带任务做冒烟测试

模板自带一个用于测试的简单任务,位于<project_slug>/users/tasks.py(对应仓库 users/tasks.py):

from celery import shared_task from .models import User @shared_task() def get_users_count(): """A pointless Celery task to demonstrate usage.""" return User.objects.count()

在 Django shell 中调用它来验证异步链路:

uv run python manage.py shell >> from <project_slug>.users.tasks import get_users_count >> get_users_count.delay()

任务会返回当前用户总数。此外,得益于django-celerybeat包,你还可以通过Django Admin 后台可视化地创建、调度周期任务,无需手写 cron 表达式。

使用 Webpack 或 Gulp 前端流水线

如果项目初始化时frontend_pipeline选择了 Webpack 或 Gulp,模板已预置Sass 编译live reloading(浏览器即时热刷新)能力:当你修改 Sass/JS 源文件时,任务运行器会自动重新构建对应的 CSS/JS 资源,并在浏览器中无刷新地热加载。

启动步骤

# 1. 确保本机安装 Node.js(模板 package.json 声明 engines.node 为 26.5,请以生成项目为准) # 2. 安装 JS 依赖 npm install # 3. 激活虚拟环境后启动开发模式 npm run dev

npm run dev并行启动两个进程:一边是静态资源构建循环,另一边是 Django 开发服务器。dev脚本由项目根目录的 package.json 定义(其scripts.dev在模板渲染时会被填充为具体的并行命令,通常基于concurrently组合 webpack-dev-server / gulp 与 Django 服务器)。

访问地址:必须走 Node 端口

⚠️关键警告:访问应用时请使用node 服务地址 http://localhost:3000(默认),绝对不要直接访问 Django 的 8000 端口,否则会出现样式错乱以及静态资源 404。

原因在于:3000 端口由 node 服务代理到 Django 应用,并在响应中注入 live reload 脚本,同时正确地为 Sass 编译产物提供服务;而 Django 自身端口(8000)并不了解这些前端资源的存在。默认端口映射可在 docker-compose.local.yml 中看到node服务暴露3000:3000端口,裸机模式下npm run dev同样以 3000 作为入口。

排错要点与日常开发提示

  1. 数据库连接失败:优先检查POSTGRES_HOST是否为localhost(裸机)而非postgres(Docker);并确认本机 PostgreSQL 已完成初始配置(密码、pg_hba.conf认证方式)。
  2. pre-commit 报错:确认已在项目目录执行过git inituv run pre-commit install,否则提交会触发大量 Linter 失败。
  3. 邮件看不到:确认你选择的mail_catcher与初始化选项一致(Mailpit / Mailtrap Local / None),并核对EMAIL_HOSTEMAIL_PORT;Console 模式下邮件直接打印在运行 Django 的终端。
  4. 异步任务不进入队列:检查local.pyCELERY_TASK_ALWAYS_EAGER是否为False,以及 Redis 是否运行在localhost:6379REDIS_URL默认值)。
  5. 前端资源 404 / 样式丢失:确认通过http://localhost:3000访问,而非 8000 端口。
  6. 完整环境变量表:涉及DJANGO_*系列变量的开发/生产默认值差异,始终以 docs/1-getting-started/settings.rst 为准。

总结

至此,你已经完成了从零开始搭建 Cookiecutter Django 裸机本地开发环境的全部关键步骤:安装依赖、创建数据库、配置环境变量、执行迁移、启动同步/异步服务器、按双层结构创建 App、搭建本地邮件捕获环境、切换 Celery 任务模式并验证异步链路,以及启用 Webpack/Gulp 前端流水线。这套工作流与 Docker 方案 互为补充——裸机模式胜在轻量与直接,Docker 模式胜在环境一致性,可根据团队与机器情况灵活选择。继续阅读 docs/2-local-development/developing-locally-docker.rst 或 docs/3-deployment/ 系列,可进一步了解容器化开发与生产部署实践,充分释放 Cookiecutter Django 的完整潜力。

【免费下载链接】cookiecutter-djangoCookiecutter Django is a framework for jumpstarting production-ready Django projects quickly.项目地址: https://gitcode.com/GitHub_Trending/co/cookiecutter-django

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询