Django实战入门:从HTTP请求到MTV架构完整跑通第一个Web应用

Django实战入门:从HTTP请求到MTV架构完整跑通第一个Web应用 很多人学 Django 的方式是先花两周看完一套教程再打开 IDE 准备做第一个项目结果发现无从下手。这不是你笨而是大多数教程把 Django 拆成了互不相干的知识点模型讲一遍、视图讲一遍、模板讲一遍、路由讲一遍每个知识点单独看都懂放到真实项目里却不知道它们怎么咬合在一起。真正的问题不是代码量不够而是缺少对 Django 运行流程的整体直觉。这篇是这个系列的第一部分目标是用最少的步骤把一个真实的 Django Web 应用跑起来并且让你理解一个 HTTP 请求从浏览器发出之后到底经过了哪些环节最后才变成你看到的页面。读完以后你应该能独立完成环境搭建、创建项目、创建应用、编写视图、配置路由、渲染模板、配置数据库以及使用 Django 自带的管理后台维护数据。这一套流程跑通之后后面再学表单、认证、类视图、部署都是在已有骨架上填肉而不是重新学一遍。本文不打算把所有 Django 语法都讲一遍而是聚焦构建真实 Web 应用这条主线。每一节会说明这一步在实际项目中解决什么问题不做什么容易错在哪里。如果你正在找一种能帮你从会看教程过渡到会做项目的学习路径这篇文章值得你读完并收藏。1. 这篇文章真正要解决的问题先交代一下这篇文章的判断Django 真正值得学的不是它有多少内置函数而是一整套 Web 开发方法论。很多人学了很久 Django遇到真实需求还是不会下手是因为一直停留在照着教程敲代码的层面没有建立起属于自己的项目骨架。1.1 为什么大多数 Django 学习者卡在中途我观察到三个典型现象。第一以知识点为中心的学习方式。今天学 QuerySet 的各种查询方法明天学模板标签好像每个知识点都学了但遇到一个从数据库取出文章列表并显示在页面上的需求时不知道代码该写在哪个文件、先写模型还是先写视图。第二不知道每一步解决什么问题。跟着教程能跑通但换了项目、换了页面就不知道如何扩展。因为教程只告诉你这样做没告诉你为什么必须这样做。第三缺乏 HTTP 请求到响应的完整心智模型。Web 框架的本质是处理 HTTP 请求浏览器发来请求框架里的某个函数处理这个请求返回一个响应。如果你不理解这条链路那么模型、视图、模板、URL 配置这些概念永远是一堆碎片。1.2 这个系列的学习路径这是一套四部分内容中的第一部分。本部分解决的是骨架问题把 Django 项目的三层结构——请求入口URL、业务逻辑View、数据模型Model——完整地建立起来。后续部分会在这个基础上继续深入更真实的功能开发。在开始之前建议你确认一件事你已经掌握了 Python 的基本语法包括函数、类、列表和字典。如果你对 Python 还很陌生建议先回头熟悉一下 Python 基础再开始 Django否则你可能分不清一个报错是 Python 语法问题还是 Django 框架问题。1.3 读完这篇文章你能获得什么一套能复用的 Django 项目创建流程而不是死记命令。对 MTV 架构下请求处理链路的具体认知而不是停留在概念层面。一个带数据库模型和管理后台的最小真实应用可以在浏览器里增删改查数据。如果你能跟着文章完整操作一遍那么你学 Django 的第一块基石就稳了。2. Django核心概念框架、MTV架构与适用场景2.1 Django到底是什么Django 是一个用 Python 编写的 Web 框架。所谓 Web 框架就是帮开发者处理 Web 开发中大量重复工作的工具集。如果没有框架你需要自己处理如何接收 HTTP 请求、如何从请求里取出参数、如何判断请求该交给哪段代码、如何拼接 HTML、如何操作数据库、如何防御常见的 Web 攻击。Django 的做法是自带电池batteries included。官方把 Web 开发中常见的功能都内置好了ORM 数据库映射、模板系统、表单处理、用户认证、Admin 管理后台、CSRF 防护、Session 管理等等。好处是你在项目初期不需要到处找第三方库也能把一个功能完整的产品做出来。坏处是框架本身比较大刚开始学的时候会觉得东西太多。这个特性决定了它的定位适合做内容型、管理型、数据型的 Web 应用而不是追求极致轻量或极致性能的边缘场景。2.2 MTV架构Django处理请求的方式很多人听说过 MVCModel-View-ControllerDjango 的架构在思想上与 MVC 一致但官方喜欢用 MTV 来描述角色职责对应目录或文件Model数据模型与数据库表对应models.pyTemplate页面模板负责展示数据templates/ 目录下的 html 文件View业务逻辑接收请求、处理数据、返回响应views.pyURL 配置路由决定哪个 URL 交给哪个 View 处理urls.py一个请求从浏览器发起到页面渲染的完整流程是浏览器发起 http://127.0.0.1:8000/ 请求。Django 根据项目根路由 urls.py 找到该 URL 对应的 View 函数。View 函数执行业务逻辑比如通过 Model 从数据库读取文章列表。View 把数据放入一个上下文context字典交给 Template。Template 渲染出最终 HTML返回给浏览器。很多人学 Django 最大的误区是试图按照 MVC 的 controller 概念去找对应文件。在 Django 里View 既是控制器也是视图你只需要记住View 是 Django 应用的大脑Model 是数据底座Template 是展示层URL 是入口。这个心智模型一旦建立后面学什么都快。2.3 Django适合做什么不适合做什么适合做的场景内容管理系统比如博客、新闻站、企业官网后台。企业内部管理系统比如运营后台、CRM、数据管理平台。电商系统和 SaaS 产品的 MVP 版本。带管理后台的 Python 后端服务。不适合做的场景极端高并发的实时应用比如一个连接百万用户的 WebSocket 网关Django 能支持但你需要额外做很多架构工作选择 Go 或 Node.js 也许更直接。只需要一个轻量 API、对性能要求极高的服务FastAPI 这类异步框架更合适。但要注意不适合不等于不能做。Django 配合 Django REST Framework同样可以构建高质量的后端 API只是你要理解它的应用边界在哪里。实际项目选型时团队熟悉哪种技术、项目需求是数据管理还是实时计算、交付周期是多长这些因素比哪个框架更强更重要。3. 环境准备Python、虚拟环境与Django安装进入实操部分。本文示例基于 Python 3.x 和 Django 5.x具体版本请以你安装时的官方信息为准。下面这套流程在 Windows、macOS、Linux 上都能执行差别只在激活虚拟环境的命令。3.1 检查Python环境在终端中执行python --version如果你的系统同时安装了 Python 2 和 Python 3可能需要使用python3 --version如果提示找不到命令需要先去 Python 官网下载安装。安装时注意勾选“Add Python to PATH”这一步能避免后面出现“python 不是内部或外部命令”的报错。Django 5.x 对 Python 版本有要求一般建议 Python 3.10 或更高版本。如果你的 Python 版本过低安装最新版 Django 时会提示版本不支持。3.2 创建虚拟环境虚拟环境的主要作用是隔离不同项目的依赖。假设你同时维护多个 Python 项目一个项目用 Django 4另一个项目用 Django 5没有虚拟环境时后安装的版本会覆盖前一个导致项目无法运行。虚拟环境为每个项目创建独立的依赖空间。在项目目录下执行python -m venv venv这会在当前目录生成一个 venv 文件夹里面保存了该项目的独立 Python 解释器和库。激活虚拟环境# macOS / Linux source venv/bin/activate # Windows venv\Scripts\activate激活后终端行首会出现(venv)标记。Windows 系统如果遇到“禁止运行脚本”的提示需要用管理员权限打开 PowerShell 执行Set-ExecutionPolicy RemoteSigned调整执行策略或者改用 CMD 运行。3.3 安装Django确认虚拟环境已激活后执行pip install django如果想安装指定版本pip install django5.1.3安装完成后用 pip show 验证pip show django也可以进入 Python 交互环境验证import django print(django.get_version())输出版本号说明安装成功。从这一步开始后续所有命令都要在虚拟环境激活的状态下执行。如果你关闭终端重新打开后忘记激活虚拟环境会发现 django-admin 命令又消失了。3.4 选择编辑器推荐使用 VS Code 或 PyCharm。VS Code 用户需要安装 Python 扩展然后用 CtrlShiftP 打开命令面板执行“Python: Select Interpreter”选择刚才创建的 venv 目录下的解释器。这一步很关键如果解释器选错VS Code 会提示找不到 Django。常见现象终端里明明安装了 Django编辑器里却提示 No module named django99% 是解释器没有指向当前项目的虚拟环境。4. 创建Django项目与应用项目和应用的区别4.1 创建项目在虚拟环境激活状态下执行django-admin startproject myblog cd myblog这里的 myblog 是项目名称。执行后生成的项目结构如下myblog/ ├── manage.py └── myblog/ ├── __init__.py ├── settings.py ├── urls.py ├── asgi.py └── wsgi.py各文件作用manage.py项目管理入口。运行开发服务器、执行数据库迁移、创建应用都是通过它执行。settings.py项目配置文件。数据库、应用注册、模板路径、静态文件等都在这里配置。urls.py项目根路由。所有 URL 的分发入口。asgi.py / wsgi.py部署到服务器时的入口文件。先运行开发服务器试试python manage.py runserver启动后访问 http://127.0.0.1:8000/ 看到 Django 默认欢迎页说明项目创建成功。这个页面确认了 Django 的开发服务器能正常工作。4.2 创建应用接下来创建 App。Django 项目是一个容器一个项目里可以有多个应用每个应用负责一个独立业务模块。比如一个内容系统可以有 article文章、user用户、comment评论三个应用。python manage.py startapp article执行后生成的目录article/ ├── migrations/ ├── __init__.py ├── admin.py ├── apps.py ├── models.py ├── tests.py └── views.py新手最容易混淆项目和应用。项目是整体配置环境应用是具体业务实现。一个项目可以包含多个应用一个应用也可以被多个项目复用。把不同业务拆到不同应用里是 Django 项目保持可维护性的关键。4.3 将应用注册到项目创建应用后需要把它注册到 settings.py 的 INSTALLED_APPS 列表里。打开 myblog/settings.pyINSTALLED_APPS [ django.contrib.admin, django.contrib.auth, django.contrib.contenttypes, django.contrib.sessions, django.contrib.messages, django.contrib.staticfiles, article, # 新增 ]如果没有这一步Django 不会识别这个应用后面执行迁移时也检测不到 article 应用的模型。注册后执行一次内置迁移python manage.py migrate这条命令会根据 Django 内置应用的迁移文件创建数据库表包括用户表、Session 表、Admin 相关表等。执行成功后项目里已经存在一个默认的 SQLite 数据库文件 db.sqlite3。顺便把语言和时区改为中文方便后续使用管理后台。修改 settings.pyLANGUAGE_CODE zh-hans TIME_ZONE Asia/Shanghai改完后重新运行服务器管理后台会显示中文界面。5. 视图、URL配置与模板让页面真正跑起来现在开始写业务代码。一个 Django 页面需要三个要素视图函数处理逻辑、URL 配置路由映射、模板页面渲染。我们会一步步把它们组装起来。5.1 第一个视图函数打开 article/views.py写一个最简单的视图from django.http import HttpResponse def index(request): return HttpResponse(Hello, Django!)再创建 article/urls.py配置 URL 与该视图的映射关系from django.urls import path from . import views urlpatterns [ path(, views.index, nameindex), ]最后修改项目根路由 myblog/urls.py把 article 应用的 URL 配置包含进来from django.contrib import admin from django.urls import include, path urlpatterns [ path(admin/, admin.site.urls), path(, include(article.urls)), ]保存后访问首页你会看到页面上显示“Hello, Django!”。这个流程虽然简单但它验证了整条链路请求进入了 article.urls找到了 index 视图视图返回了一个响应。这里有一个新手常见错误写了 article/urls.py但在项目 urls.py 里忘了用 include 引入结果访问页面时永远 404。URL 配置的顺序很重要Django 从上到下匹配遇到第一个匹配的 URL 就停止。5.2 用模板渲染HTML返回纯文字不算真实页面。模板系统解决的是“如何生成动态 HTML”。在 article 应用下创建 templates/article/index.html!DOCTYPE html html langzh-hans head meta charsetUTF-8 title文章首页/title /head body h1文章列表/h1 p{{ message }}/p /body /html修改 views.pyfrom django.shortcuts import render def index(request): context { message: 欢迎来到 Django 真实项目实战, } return render(request, article/index.html, context)刷新页面看到“欢迎来到 Django 真实项目实战”说明模板渲染成功。render 函数的第一个参数是请求对象第二个参数是模板路径第三个参数是 context 字典模板中可以通过{{ message }}使用字典中的值。Django 会自动到每个已注册应用的 templates 目录下查找模板不用手动指定绝对路径。模板文件名里的article/前缀是为了避免不同应用下有同名模板文件时互相覆盖。5.3 模板变量与循环真实页面通常要展示列表数据。在 views.py 中传入一个列表def index(request): articles [ {id: 1, title: Django 入门, author: 张三}, {id: 2, title: Python 进阶, author: 李四}, ] context { articles: articles, page_title: 文章列表, } return render(request, article/index.html, context)在模板中遍历这个列表h1{{ page_title }}/h1 ul {% for article in articles %} li{{ article.title }} - {{ article.author }}/li {% endfor %} /ulDjango 模板语言只有两种主要语法{{ variable }}输出变量的值。{% tag %}执行逻辑如 for 循环、if 判断。模板不是 Python它刻意限制了逻辑能力目的是让页面展示代码保持简单。不要在模板里写复杂业务逻辑业务逻辑应该放在视图里。5.4 静态文件与样式页面还需要 CSS、JS、图片这类静态文件。Django 的开发服务器会通过 StaticFilesFinder 查找静态文件。在 article 应用下创建 static/article/style.cssbody { font-family: Microsoft YaHei, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; } h1 { color: #2c3e50; }在模板头部加载静态文件{% load static %} !DOCTYPE html html langzh-hans head meta charsetUTF-8 link relstylesheet href{% static article/style.css %} title文章首页/title /head开发阶段 Django 能直接处理静态文件但部署到服务器后静态文件通常交给 Nginx 等 Web 服务器托管Django 本身不负责高性能地提供静态文件。这个差异要在部署时特别注意。6. 数据库模型与管理后台真实应用的数据底座前面列表数据是写死在视图里的真实项目的数据要存到数据库。Django 用 ORM对象关系映射来操作数据库你定义 Python 类Django 自动创建对应的数据库表查询、新增、修改、删除都通过 Python 对象完成不需要写原生 SQL。6.1 定义模型打开 article/models.py定义一个文章模型from django.db import models class Article(models.Model): title models.CharField(max_length200) author models.CharField(max_length50) content models.TextField() created_at models.DateTimeField(auto_now_addTrue) def __str__(self): return self.title字段说明CharField短文本字段适合标题、作者名必须指定 max_length。TextField长文本字段适合文章正文。DateTimeField日期时间字段auto_now_addTrue 表示创建记录时自动写入当前时间。__str__方法是给 Django 后台用的显示对象时返回文章标题。这段代码定义的是“数据模型”还不能直接操作数据库。要让 Django 知道模型变化需要两步先生成迁移文件再执行迁移。6.2 生成迁移并执行python manage.py makemigrations article python manage.py migratemakemigrations 做的事情是“把模型的变化记录成迁移脚本”migrate 才是“真正把脚本执行到数据库”。第一次接触时容易把这两步混在一起。如果你修改了模型一定要重新执行 makemigrations否则数据库不会感知到变化。执行成功后models 里的 Article 类就在数据库里对应了一张 article_article 表。6.3 注册模型到管理后台Django Admin 是它最受欢迎的功能之一。只要把模型注册到 admin.py就能得到一个可用的后台管理界面不需要自己写页面。修改 article/admin.pyfrom django.contrib import admin from .models import Article admin.site.register(Article)创建超级管理员账号python manage.py createsuperuser按提示输入用户名、邮箱、密码。密码输入时不会显示这是正常现象。Django 有密码复杂度要求如果提示太弱换一个包含字母和数字的长密码。然后访问 http://127.0.0.1:8000/admin/ 使用刚创建的账号登录。你会看到“文章”的增删改查界面可以点击“增加”创建一篇真实文章。这一步很重要因为之后首页的列表数据将来自这里而不是写死在代码里的列表。6.4 在视图中使用数据库数据修改 views.py把写死的列表换成从数据库查询from django.shortcuts import render from .models import Article def index(request): articles Article.objects.all().order_by(-created_at) context { articles: articles, page_title: 文章列表, } return render(request, article/index.html, context)Article.objects.all() 查询所有文章记录order_by(-created_at) 按创建时间倒序排列。在后台添加几篇文章回到首页刷新你会看到刚添加的文章自动出现在页面上。到这里一个最小可用的 Django 数据流闭环形成了后台写入数据 → 数据库存储 → 视图查询 → 模板展示。这个闭环就是绝大多数内容型 Web 应用的核心骨架。6.5 数据库配置说明默认情况下Django 使用 SQLite你不需要安装任何额外的数据库服务。对于入门和中小规模项目SQLite 够用且零维护成本。真实项目中更常用 MySQL 或 PostgreSQL。切换数据库只需要修改 settings.py 中的 DATABASES 配置代码里的 ORM 查询基本不用改。这是 Django ORM 带来的好处。但要注意切换数据库涉及数据库驱动安装和连接参数属于部署阶段的工作建议在测试环境验证后再操作操作前备份数据。7. 常见问题与排查思路下面是初学者最常见的问题和排查方法。问题现象可能原因排查方式解决方案运行 runserver 提示端口被占用8000 端口已被其他进程使用看报错信息中的端口号python manage.py runserver 8080换端口访问页面一直 404App 没有注册或路由器没有 include检查 settings.py INSTALLED_APPS 和项目 urls.py注册 App并用 include 引入子路由提示 No module named django当前 Python 环境不是虚拟环境终端执行which python或where python激活虚拟环境后重新安装依赖提示 No module named article应用目录不在项目可导入路径下检查 article 目录是否存在__init__.py用 startapp 重新创建不要手动乱建目录执行 makemigrations 没有生成文件App 未注册到 INSTALLED_APPS检查 settings.py注册 App 后重新执行迁移时报 No migrations to apply数据库已有对应表或迁移文件状态异常检查应用 migrations 目录与数据库表在测试环境中重建数据库再迁移模板中变量显示为空context 键名与模板变量名不一致对比视图 context 与模板 {{ }} 的名称统一变量名页面中文乱码文件编码或数据库字符集问题确认模板meta charsetUTF-8环境变量统一使用 UTF-8 编码后台登录提示密码太弱Django 默认密码策略要求复杂度按提示调整密码使用至少 8 位、包含字母和数字的密码修改模型后数据库无变化忘记执行生成迁移和迁移执行 makemigrations migrate每次修改模型后都要执行这两步遇到问题时一个先后的排查顺序是先看终端命令行有没有报错再看 Django 调试页面提示的异常位置最后检查 settings.py 和 urls.py 这两个最容易出错的配置文件。8. 最佳实践与工程建议到这里你已经跑通了一个带数据库的 Django 应用。接下来是在真实项目中需要养成的工程习惯。8.1 项目结构一个项目不要只放一个应用。按业务边界拆分比如 article、user、comment 分开。应用命名使用单数名词比如 ArticleApp 没有必要直接叫 article。模板文件在应用下加一层与应用同名的子目录防止多个应用模板互相覆盖。8.2 配置管理不要把数据库密码、SECRET_KEY 等敏感信息硬编码在 settings.py 里通过环境变量读取。SECRET_KEY 是 Django 进行加密签名的基础密钥泄露后可能导致 Session 伪造生产环境必须设为随机值。生产环境必须关闭 DEBUG。DEBUGTrue 时Django 会输出详细异常页面泄露代码路径和配置信息非常危险。8.3 数据库与迁移每次修改模型都要生成迁移文件并提交到版本控制不要把迁移文件随意删除。生产环境执行迁移前先备份数据库并在测试环境验证迁移脚本。不要在生产环境直接运行 migrate 而不检查迁移顺序。多人协作时迁移文件冲突要用 merge 方案解决。8.4 安全习惯Admin 后台是管理系统的入口账号必须使用强密码。可以修改 admin 后台的 URL 路径降低被扫描工具探测到的概率。做法很简单在项目 urls.py 里把 path(admin/, ...) 改成不明显的路径。Django 内置了 CSRF 防护、XSS 转义、SQL 注入防护使用内置功能时不要试图关闭这些中间件。8.5 依赖锁定一个项目应该有独立的 requirements.txt固定依赖版本。在虚拟环境中执行pip freeze requirements.txt后面换机器或部署时执行pip install -r requirements.txt这样能保证依赖环境一致避免出现“本地能跑部署到服务器跑不了”的问题。9. 总结与后续学习方向第一部分到这里就结束了。你现在已经完成了一个真实 Django 应用的骨架搭建创建了项目和应用理解了 MTV 架构体验了从 URL 到视图再到模板的完整请求链路并且通过定义模型、执行迁移、注册 Admin让数据在后台和前端之间真正流动起来。这个骨架的核心价值在于你已经知道一个 Django 项目的基本组成后面学习任何新知识点都有地方安放。学表单时你知道它服务于视图学认证时你知道它是模型层和视图层之间的协作学部署时你知道这些问题都属于配置和运维层面。接下来的实践方向建议按顺序进行给 Article 模型增加分类和标签字段扩展数据关联关系。做一个文章详情页学会从数据库中获取单条记录并处理 404。学习 Django 内置表单实现通过前台页面提交文章。学习基于类的视图减少重复代码。了解 Django REST Framework为前端或其他系统提供 JSON API。最后再学习 Nginx、Gunicorn 与 Django 的部署组合。很多人在学会创建项目之后会急着学更多高级功能。但这里我更建议你先把当前的模型、视图、模板、Admin 这条链路多加练习用自己的业务场景把它改造一遍。比如做一个图书管理、笔记管理、日程管理的小应用把后台添加的数据展示到前台。做通一个再学下一个比一次性学完所有功能更有效。下一篇教程会继续推进这个项目把静态首页变成真正可以承载内容的系统包括详情页、列表筛选和分页。你可以先把当前骨架跑熟准备进入下一阶段。