资讯动态

Django从配置到运行:项目骨架、settings与请求链路全解析

发布时间:2026/10/16 1:30:52 来源:尧图企业网站定制
很多人第一次接触Django最容易卡住的其实不是写代码而是装完环境之后站在一堆陌生文件前面发呆settings.py、urls.py、manage.py……每个文件看起来都有事又不知道谁负责什么。我见过不少同事项目从django-admin startproject开始到runserver报错退场整个过程都没超过十分钟。所以这次我打算把“从配置到运行”这条线完整串一遍。不是教你怎么背命令而是把每一步背后的逻辑讲清楚——环境为什么要这么搭、配置文件里每个开关到底在管什么、数据库是怎么“零配置”跑起来的、以及你敲下runserver之后Django 在背后到底做了哪些事。这篇适合完全没接触过 Django 的纯新手也适合那种“能跑但说不清原理”的人。1. 搭建独立运行环境为什么每个项目都要自己的“虚拟厨房”1.1 先选对 Python 版本再谈安装开始之前建议你先确认本机的 Python 版本。我通常要求 3.10 以上越新越好。Django 对 Python 版本有明确的下限要求如果你装的是老版本 Python后续可能连pip install django都过不去或者装上了也跑不起来报一些莫名其妙的语法错误。检查版本的方式很简单python --versionWindows 用户如果直接敲python无效可以试试py --version。这个细节很多人吃亏命令行里认不到python不代表你没装 Python只是可执行程序没注册到 PATH 里用py这个启动器就能绕过去。1.2 创建虚拟环境并激活我强烈建议你永远不要在全局环境里直接pip install django。原因我后面细说先看命令。在项目根目录下执行python -m venv .venv这会生成一个.venv文件夹里面是一套独立的 Python 解释器和 pip 环境。接下来要“激活”它Windows PowerShell.venv\Scripts\Activate.ps1macOS / Linuxsource .venv/bin/activate激活之后你会注意到命令行提示符前面多了一个(.venv)这说明你已经在虚拟环境里了。这时候再用 pip 安装的包只会进到这个.venv里跟外面的系统环境彻底隔开。1.3 为什么不推荐直接装在全局环境我见过太多次这样的场景某台开发机上装了几十个项目每个项目依赖的 Django 版本不一样有的项目要 2.2有的要 4.2还有一堆第三方库互相打架。pip 默认是“覆盖式”安装后装的高版本会直接把旧版本顶掉于是老项目某天突然启动不了了。虚拟环境相当于给每个项目单独准备了一套厨房调料、锅具、灶台都是自己的互不串味。哪怕你在 A 项目里把 Django 升级到最新版B 项目里那个老版本也纹丝不动。这个习惯越早养成越好别等项目多了再回头补课。1.4 安装 Django 并锁定版本激活虚拟环境之后安装 Djangopip install django4.2.16为什么要手动指定版本因为 Django 的大版本之间配置写法、默认行为、第三方库兼容性差异很大。比如 Django 3.x 和 4.x 的url写法就有区别5.x 对 Python 版本要求更高。如果你直接pip install django装到的是当前最新版但网上大量教程写的是 3.x 或 4.x 的写法照抄很容易踩坑。我个人推荐从 4.2 这个长期支持版本入门而不是追最新大版本。原因很简单LTS 版本维护周期长资料多第三方生态适配成熟遇到问题搜解决方案最方便。安装完验证一下python -m django --version看到版本号输出环境这一关就算过了。2. startproject 生成的项目骨架每个文件的来头与职责2.1 命令里的“点号”到底意味着什么进入项目目录执行django-admin startproject config .注意最后这个点号很多人容易忽略它。它的意思是在当前目录直接生成项目文件不再额外套一层目录。如果你漏写这个点执行startproject configDjango 会创建一个config文件夹并在config里再套一层config最终目录层次变成config/config/启动时还容易因为路径问题找不到配置。新手包里最常见的运行失败有一半是这个原因。2.2 生成的文件逐个拆解命令执行完后当前目录下会多出这些东西config/ __init__.py settings.py urls.py asgi.py wsgi.py manage.py按我的习惯把每个文件负责的事列成一张表比反复翻文档管用得多文件职责manage.py命令行工具入口。runserver、migrate、startapp等操作都靠它转发命令config/__init__.py让config目录成为一个 Python 包config/settings.py项目的总配置中心数据库、应用、中间件、模板、时区全在这里config/urls.pyURL 路由表决定浏览器访问哪个地址时由哪段代码响应config/asgi.py异步服务入口跑异步接口或某些部署方式时使用config/wsgi.py同步服务入口生产环境常用的gunicorn等工具需要它其实前三个文件是你日常打交道最多的asgi.py和wsgi.py前期基本不用动。2.3 Project 和 App 的概念区别这里必须花两分钟说清楚一个概念因为后面所有内容都建立在这上面。Django 里Project 是整站它管的是全局配置装哪些应用、用什么数据库、URL 怎么分发。App 是功能模块比如一个博客系统里有文章模块、评论模块、用户模块每个模块可以拆成一个 app。Project 是一个完整的“容器”App 是容器里的“服务单元”。一个 Project 可以包含多个 App一个 App 也可以被多个 Project 复用。有人把 Project 比作房子的主体结构App 比作房间里的家具电器我觉得挺贴切。这篇我们先不创建 App目的就是先把框架本身跑起来理解 Project 层面是怎么回事。3. settings.py 逐项拆解真正的配置工作从读懂总控台开始3.1 安全三兄弟SECRET_KEY、DEBUG、ALLOWED_HOSTS打开config/settings.py前几个变量就够你琢磨一阵子了。SECRET_KEY是 Django 的签名密钥会话、密码重置、CSRF 校验等一堆安全机制都依赖它。这个值绝对不能泄露更不能传到公开的代码仓库里。开发阶段无所谓以后部署时一定要改成环境变量注入的方式。紧跟着的DEBUG True是开发模式下的调试开关。它的作用是页面报错时直接把完整的异常堆栈渲染在浏览器里包括具体到哪一行代码出错。这对开发期排查问题极其友好。但是你要记住DEBUG False之后Django 不再帮你处理静态文件而且你必须配置ALLOWED_HOSTS否则直接给你一个 400 Bad Request。这俩是联动的。很多人部署时第一步就把DEBUG改成False结果页面全挂了其实就是没理解这个关联。3.2 已安装应用与中间件框架默认配好的骨架往下看INSTALLED_APPS里默认有这些django.contrib.admin自带的后台管理界面django.contrib.auth用户认证体系django.contrib.contenttypes内容类型框架权限和 admin 的底层依赖django.contrib.sessions会话机制django.contrib.messages临时消息提示django.contrib.staticfiles静态文件管理很多新手一看这里就慌了我啥还没写呢你装这么多东西干啥其实这些是 Django 的“标准厨房配菜”它们和后面的MIDDLEWARE、数据库迁移是配套的。比如sessions要配合会话中间件auth要配合认证中间件游戏规则是爹妈都帮你定好了你暂时不用动。MIDDLEWARE列表则会按顺序处理每一个请求。我习惯把它理解成一条快递分拣流水线请求进来后要过一个又一个站点每个站点只检查自己那部分事。比如安全中间件检查请求头会话中间件加载 session认证中间件绑定当前用户。顺序很重要尤其SessionMiddleware必须放在AuthenticationMiddleware前面因为认证要依赖会话先取到用户。3.3 模板、路由、数据库与静态文件偏业务侧的默认配置ROOT_URLCONF config.urls这行是让 Django 知道“路由表在哪个文件”。你以后学多项目部署时每个项目的 URLconf 是独立的。TEMPLATES是一个列表里面配置模板引擎、模板目录、上下文处理器。默认的配置适合绝大多数场景你暂时只需要知道它负责在“返回 HTML 页面”的时候去哪找模板文件、渲染时默认注入哪些变量。DATABASES默认长这样DATABASES { default: { ENGINE: django.db.backends.sqlite3, NAME: BASE_DIR / db.sqlite3, } }这配置的意思是用自带 SQLite 数据库数据库文件就生成在项目根目录下叫db.sqlite3。这个我们下一节重点讲。往下还有几个容易被忽略但很常见的坑LANGUAGE_CODE en-usTIME_ZONE UTC。如果你不改成中文和北京时间后面 admin 后台界面是英文的时间还会差八个小时。我的习惯是LANGUAGE_CODE zh-hans TIME_ZONE Asia/Shanghai USE_TZ True这里要特别解释一下USE_TZ True的副作用开启后Django 存数据库的时间永远是 UTC 时间页面展示时再按TIME_ZONE转换成本地时间。也就是说你只改了TIME_ZONE而不改USE_TZ直接查数据库时看到的还是 UTC容易误以为“时间没改过来”。这是新手极容易困惑的点。STATIC_URL static/是静态文件 URL 前缀CSS、JS、图片文件访问路径都从它出发。开发模式下不用额外处理部署时需要配合whitenoise或反向代理。看完这一节你应该已经意识到一件事配置文件里没有“晦涩难懂”的东西只有你没查过文档的东西。每个变量都在回答一个具体问题只是没人把它们串起来讲。4. 数据库“零配置”起步SQLite 与迁移命令的配合逻辑4.1 为什么默认数据库是 SQLite刚接触 Django 的人经常问我是不是得装个 MySQL 或者 PostgreSQL 才能跑起来不用。Django 默认的 SQLite 是一个嵌入式数据库整个数据库就是一个文件不需要额外安装服务不需要账号密码也不需要监听端口。开发阶段用它极其合适因为你大部分时间在调试逻辑而不是压测性能。类比一下SQLite 就像你自己工位上的记事本MySQL 和 PostgreSQL 像公司文档管理系统。记事本在自己桌上用方便但多人协作、并发写入、海量查询时就不顶用了。所以开发期用 SQLite 起步没问题部署上线时再切换到 PostgreSQL 是更稳妥的做法。4.2 migrate 到底迁移了什么配置完成之后执行python manage.py migrate你会看到一串Applying ... OK的输出。这个命令做的事是把INSTALLED_APPS里那些内置应用的表建到db.sqlite3里。比如auth应用的用户表sessions应用的会话表admin应用的操作记录表。这里要讲清楚一个核心概念migration 是模型变化的版本记录不是一次性建表脚本。Django 里模型类定义在 app 的models.py中。当你修改模型后通过python manage.py makemigrations生成一个迁移文件这个文件记录了“模型从上一个版本变成了什么”。然后执行python manage.py migrateDjango 会去查django_migrations表看哪条迁移记录还没执行过按顺序补执行。所以你会发现migrate重复执行一百次也不会重复建表因为每一条迁移执行过后都会被登记。这个机制保证了多环境同步时不会有人漏掉一次变更。你可以打开数据库看看建了哪些表。用命令python manage.py dbshell然后输入.tables查看表列表输入.quit退出。这种方式不依赖任何第三方数据库工具日常查数据很方便。4.3 顺手创建一个后台管理账号Django 自带那个 admin 后台不创建账号是进不去的。执行python manage.py createsuperuser按提示输入用户名、邮箱、密码之后启动服务访问http://127.0.0.1:8000/admin/就能用刚创建的账号登录。这个后台在你后续开发 app、注册模型之后会非常有用——CRUD 操作界面化很多临时数据维护根本不用写代码。现在先知道有这回事就行。5. 让第一个请求真正跑通URLconf、视图函数与浏览器之间的链路5.1 runserver 启动前后的机制现在执行python manage.py runserver看到Starting development server at http://127.0.0.1:8000/这行输出说明服务已经起来了。默认绑定的是127.0.0.1:8000只能本机访问。想让局域网内其他设备也能访问改成python manage.py runserver 0.0.0.0:8000这个命令会让 Django 监听所有本机网络接口同事手机和电脑就能通过你的局域网 IP 访问了。还有一点必须知道开发服务器带着自动重载机制。你改了.py文件它会自动检测到变化并重启。但新增了一些特殊目录或配置文件时它有时反应不过来这时候手动 CtrlC 再启动一遍最省心。另外这个开发服务器是按单进程跑的并发能力远不如生产部署方式。它能帮你快速调试业务逻辑但别拿它当生产服务器扛流量。5.2 写一个最简视图并配好路由打开config/urls.py默认内容只有 admin 的路由。我们做一件小事让首页有反应。在config目录下新建一个views.py写入from django.http import HttpResponse def index(request): return HttpResponse(你好Django 跑通了)然后把urls.py改成from django.contrib import admin from django.urls import path from config import views urlpatterns [ path(, views.index), path(admin/, admin.site.urls), ]刷新浏览器访问http://127.0.0.1:8000/你应该能看到那段中文文本。这里我说明一下我选择把视图函数放在config/views.py只是为了演示方便。后面你创建了真正的 app视图应该放在 app 自己的views.py里。现在这样写是为了把链路打通别在“文件该放哪”这种问题上纠结太久。5.3 请求的完整链路从 URL 到响应的每一步这个过程值得仔仔细细走一遍因为整个 Django 的生命周期就是这段路的循环浏览器发出请求GET /Django 先根据ROOT_URLCONF找到config/urls.py把这个文件里的urlpatterns当成一张路由表从上到下匹配请求路径。匹配到path(, views.index)后调用views.index(request)这个函数。函数执行完返回一个HttpResponse对象Django 再把它封装成 HTTP 响应传回给浏览器。这里面最核心的认知是视图函数只负责接收请求、返回响应不负责思考“路由怎么匹配”。路由匹配是 URLconf 的事业务处理是视图函数的事两者分开各管一摊。你可以在这条链路上做几个小实验加深印象访问一个不存在的路径比如/abc/在DEBUG True时你会看到一个漂亮的 404 调试页面明确告诉你哪个路由规则被尝试过、为什么没匹配上。把urls.py里加一行path(hello/, views.index)访问/hello/你会发现同一个视图函数可以对应多个 URL。这两个小实验做完你对“路由表”的理解会比读十遍文档都深刻。6. 运行期高频坑端口占用、时间差、404 与改完不生效的排查清单6.1 现象与原因对照表我把自己和身边人踩过的坑汇总了一张表遇到对应现象直接查原因现象常见原因解决办法提示端口 8000 已被占用上次启动没关干净换端口跑python manage.py runserver 8080或杀掉占用进程数据库表没建出来还没执行 migrate直接执行python manage.py migrate创建超级用户报错表尚未迁移先迁移再创建顺序不能反修改代码后页面没变化自动重载没触发手动 CtrlC 重启 runserver访问返回 400 Bad RequestDEBUGFalse且ALLOWED_HOSTS没配好把域名或 IP 加进ALLOWED_HOSTS时间显示差 8 小时时区配置和 USE_TZ 的联动没搞清检查TIME_ZONE与USE_TZ组合django-admin命令找不到虚拟环境没激活先激活.venv再执行命令6.2 环境与命令层面的三个典型坑第一个坑装了 Django 但django-admin提示不存在。九成情况是你没激活虚拟环境。检查方式很简单——命令行前面有没有(.venv)前缀。如果没有激活之后一切恢复正常。第二个坑Windows 下pip命令报红。不要慌着重装 Python。如果你同时装了多个 Python 版本用python -m pip这种形式可以明确指定用哪个解释器执行命令比单独敲pip更可控。第三个坑数据库文件被误删。SQLite 的数据全在db.sqlite3这个文件里如果你把它删了所有迁移记录和业务数据都没了。有些人不知道这一点随手清空了文件重启项目后看到“一堆表不存在”还以为是程序坏了。其实重新执行一次migrate就能重建表但数据是找不回来的。6.3 配置层面的安全习惯与版本控制建议配置上最需要养成的好习惯是把SECRET_KEY和数据库文件从代码仓库里剔除出去。在项目根目录建一个.gitignore至少写上这几行.venv/ db.sqlite3 __pycache__/ *.pyc staticfiles/这样做的好处很明显密钥不会随着代码仓库共享出去数据库文件不会因为测试操作反复冲突。我见过不止一个团队因为把db.sqlite3提交进仓库导致同事 pull 下来后数据库互相覆盖排错排了一下午。如果非要给一个顺序建议我建议你按这条主线走先跑通默认页面再写最简视图再搞清楚迁移机制最后再回头逐行阅读 settings.py。从上到下把配置啃一遍看着很笨但对后来的调试能力帮助很大。Django 的“配置到运行”看似琐碎真正跑通之后你得到的不仅是一个启动成功的项目更是一张完整的请求处理地图。后续不管是加 App、建模型、接数据库还是上线部署都是在这张地图上继续添路标而已。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑