环境搭建与第一个“Hello, World”:Django 项目结构与 MTV 模式详解
2026/6/10 7:29:04 网站建设 项目流程

作者:IT策士

10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在公众号、今日头条持续发布最新文章,助你少走弯路。

无论你是刚跨入 Web 开发大门的新手,还是想从其他框架迁移过来的进阶开发者,理解 Django 的“骨架”和“灵魂”都是绕不开的第一步。本文不会只丢给你一堆命令和概念,而是通过环境搭建->Hello World->项目结构剖析->MTV 实战这一条线,部署和可亲手验证的例子,带你深入浅出地吃透 Django 的启动原理。

读完你会获得:

  • 可运行的最小 Django 项目

  • 对项目结构每个文件的清晰认知

  • 通过控制台打印理解 Django 请求生命周期

  • MTV 模式下的模型建立、视图渲染、模板展示的全流程


1. 环境准备:搭建干净的 Python 舞台

1.1 确认 Python 版本

Django 4.2 LTS 需要 Python 3.8+,Django 5.0+ 要求 Python 3.10+。打开终端执行:

$ python3--versionPython3.12.3

如果你的系统同时存在 Python 2,请始终使用python3pip3命令。

1.2 创建虚拟环境

虚拟环境能隔离项目依赖,避免污染全局 Python。在项目父目录下:

$ python3-mvenv django_env $sourcedjango_env/bin/activate# Linux/macOS# 或 Windows 下: django_env\Scripts\activate

激活成功后,终端提示符前会出现(django_env)标识。控制台输出类似:

(django_env)user@host:~/projects$

1.3 安装 Django 并验证

(django_env)$ pipinstalldjango Collecting django Downloading Django-4.2.11-py3-none-any.whl(8.1MB)... Successfully installed asgiref-3.8.1 django-4.2.11 sqlparse-0.5.0(django_env)$ python-mdjango--version4.2.11

看到版本号即为安装成功。至此环境准备完毕。


2. 第一个 Django 项目:从零到“火箭”

2.1 创建项目

使用django-admin startproject命令,我们创建一个名为mysite的项目:

(django_env)$ django-admin startproject mysite(django_env)$cdmysite(django_env)$lsmanage.py mysite/

控制台没有任何输出是正常的—— Django 会默默生成一套初始文件。我们来看目录树:

mysite/ ├── manage.py └── mysite/ ├── __init__.py ├── settings.py ├── urls.py ├── asgi.py └── wsgi.py

2.2 运行开发服务器,看见欢迎页

Django 自带轻量级开发服务器,绝对不要用于生产环境。执行:

(django_env)$ python manage.py runserver Watchingforfilechanges with StatReloader Performing system checks... System check identified no issues(0silenced). May13,2026-10:23:45 Django version4.2.11, using settings'mysite.settings'Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.

打开浏览器访问http://127.0.0.1:8000/,你会看到 Django 的“小火箭”欢迎页。此时控制台会输出访问日志:

[13/May/202610:24:01]"GET / HTTP/1.1"20016364

这个页面是django.views.debug默认提供的,说明项目骨架已能正常响应请求。在没有添加任何视图时,Django 的 URL 配置会引导到这个调试页面。

现在,我们要让它输出我们自己的 “Hello, World”。


3. 第一个应用与 Hello World:让控制台开口说话

Django 哲学是:一个“项目”可以包含多个“应用”。我们把业务逻辑放在应用里。

3.1 创建应用

(django_env)$ python manage.py startapp hello

控制台同样无输出,但目录下多了一个hello/文件夹:

hello/ ├── __init__.py ├── admin.py ├── apps.py ├── migrations/ │ └── __init__.py ├── models.py ├── tests.py └── views.py

3.2 编写视图:让函数返回文字,并向控制台打印

打开hello/views.py,写入:

from django.httpimportHttpResponse from datetimeimportdatetime def say_hello(request):# 这行会打印到运行服务器的终端上print(f"[{datetime.now()}] say_hello 视图被访问了!")returnHttpResponse("Hello, World! 你好,世界!")

print正是我们观察请求时机的最直接方式。

3.3 配置 URL 映射

光有视图不行,必须告诉 Django 什么路径对应什么视图。在hello/目录下新建urls.py

from django.urlsimportpath from.importviews urlpatterns=[path('', views.say_hello,name='hello'),]

然后修改项目总路由mysite/urls.py,将hello应用的路由包含进来:

from django.contribimportadmin from django.urlsimportpath, include urlpatterns=[path('admin/', admin.site.urls), path('hello/', include('hello.urls')),# 新增]

3.4 注册应用(重要)

Django 需要知道有哪些应用,这样它才能找到模板、静态文件等。编辑mysite/settings.py,在INSTALLED_APPS列表中添加:

INSTALLED_APPS=['django.contrib.admin','django.contrib.auth',...'hello',# 注册我们的应用]

3.5 启动服务器,见证 Hello World

重新运行服务器(如果之前没停,它会自动重载):

(django_env)$ python manage.py runserver

浏览器访问http://127.0.0.1:8000/hello/,页面显示:

同时,控制台会打印:

[2026-05-1310:30:15]say_hello 视图被访问了![13/May/202610:30:15]"GET /hello/ HTTP/1.1"20030

进阶点:这里的print输出与 Django 的请求日志出现在同一终端。在生产环境中(如使用 Gunicorn),print会输出到服务器日志流,是快速调试的利器。但请记得调试完删除print,正式环境请使用标准logging模块。

这样,我们就有了第一个会说话的 Hello World。更重要的是,你看到了请求 → 路由 → 视图的链路,控制台打印就是这链路的心跳。


4. 项目结构深度解剖:每个文件都在干什么?

新手往往会被一堆.py文件吓到,下面我们把它们拆开揉碎。结合“初始化 + 运行”的控制台输出,你会理解每个文件的存在意义。

4.1manage.py:项目的管家

$catmanage.py#!/usr/bin/env python"""Django's command-line utility for administrative tasks.""" import os import sys def main(): os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')try: from django.core.managementimportexecute_from_command_line except ImportError as exc: raise ImportError(...)execute_from_command_line(sys.argv)

它做的事:设置环境变量DJANGO_SETTINGS_MODULE,指向mysite.settings,然后把命令行参数交给 Django 的命令执行器。我们常用的runserverstartappmigrateshell都是由此进入。

你运行的python manage.py runserver之所以能启动服务器,就是因为它加载了mysite.settings中的配置(包括已安装应用、中间件等)。

4.2 项目配置包mysite/

__init__.py

空文件,告诉 Python 这个目录是一个包。通常不需要动它。

settings.py—— 项目的控制中心

打开这个文件,关键部分:

BASE_DIR=Path(__file__).resolve().parent.parent# 项目根目录SECRET_KEY='django-insecure-xxxx'# 密钥,加密签名用,绝对要保密DEBUG=True# 开发模式,提供详细错误页面,生产环境必须 FalseALLOWED_HOSTS=[]# 允许访问的主机名,生产需配置INSTALLED_APPS=[...]# 所有安装的应用MIDDLEWARE=[...]# 中间件栈,处理请求/响应的钩子ROOT_URLCONF='mysite.urls'# 根 URL 配置TEMPLATES=[...]# 模板引擎配置DATABASES={'default':{'ENGINE':'django.db.backends.sqlite3',...}}# 数据库

控制台相关:当你运行runserver时,终端会输出:

Django version4.2.11, using settings'mysite.settings'

这印证了manage.py所设的环境变量。

urls.py—— 请求的交通指挥

前文我们已经修改过它。初始内容通常只有admin/路由。每个path()将 URL 模式映射到一个视图函数。这里的“include”机制允许层层分发,形成树状路由结构,特别适合大型项目。

wsgi.pyasgi.py—— 通往生产环境的门
  • WSGI(Web Server Gateway Interface):同步接口,传统部署使用(如 Gunicorn + Nginx)。

  • ASGI(Asynchronous Server Gateway Interface):异步接口,支持 WebSocket、长连接。

我们使用的runserver开发服务器,其实就是启动了一个简单的 WSGI(或 ASGI)服务器。你可以通过python manage.py runserver的控制台输出看到协议类型(默认 WSGI,如果安装了异步支持可能切换)。通常这些文件不需要改动,除非要自定义应用加载。

4.3 应用结构hello/

每个应用是一个可复用的模块:

  • views.py:存放视图函数或类,处理请求并返回响应。我们已经在这里放了say_hello

  • models.py:定义数据模型(表结构),这是我们接下来要玩的重点。

  • admin.py:注册模型到 Django 自带的管理后台。

  • apps.py:应用配置,可在settingsINSTALLED_APPS中使用'hello.apps.HelloConfig'这种完整的路径。

  • migrations/:存放数据库迁移文件。每当你修改模型并执行makemigrations,Django 会在这里生成 Python 脚本,记录数据库变更。

  • tests.py:单元测试。建议一写应用就写好测试。

理解了结构,我们就可以深入 MTV 模式,让程序不只是返回字符串,而是动态地从数据库取数据并渲染漂亮页面。


5. MTV 模式深入剖析:模型、模板、视图的协奏曲

Django 常被归类为“MVC”框架,但它自己称为MTV

  • Model:数据存取层,处理数据库和业务规则。

  • Template:表现层,决定数据如何展示。

  • View:业务逻辑层,接收请求,处理数据,调用模板返回响应。

URL 分发器不属于 MTV 字母,但同样重要:它把 URL 映射给 View。我们通过一个完整的例子来体现:创建一个博客帖子,在视图里查询并打印,然后显示在模板中。

5.1 创建 Post 模型

编辑hello/models.py

from django.dbimportmodels class Post(models.Model): title=models.CharField(max_length=100)content=models.TextField()created_at=models.DateTimeField(auto_now_add=True)def __str__(self):returnself.title

我们定义了一个Post表,有标题、正文和自动添加的创建时间。

5.2 生成并执行迁移,观察控制台

迁移是 Django 的“时光机”,能安全地变更数据库结构。首先生成迁移文件:

(django_env)$ python manage.py makemigrations hello Migrationsfor'hello':hello/migrations/0001_initial.py - Create model Post

控制台会告诉我们生成了0001_initial.py,并简述它做了什么。你可以通过sqlmigrate查看对应的 SQL 语句(这里展示输出):

(django_env)$ python manage.py sqlmigrate hello 0001 BEGIN;-- -- Create model Post -- CREATE TABLE"hello_post"("id"integer NOT NULL PRIMARY KEY AUTOINCREMENT,"title"varchar(100)NOT NULL,"content"text NOT NULL,"created_at"datetime NOT NULL);COMMIT;

新手注意sqlmigrate并不执行迁移,只是打印 SQL,帮助我们验证。实际应用到数据库要执行migrate

(django_env)$ python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, hello, sessions Running migrations: Applying hello.0001_initial... OK

终端清晰地显示了应用的迁移名称和状态OK。现在数据库里已经有了hello_post表。

5.3 用 Django shell 玩转模型 —— 控制台输出的绝佳示例

Django 提供了一个增强版 Python 交互环境,自动加载项目设置和模型:

(django_env)$ python manage.py shell

进入后,我们可以随心所欲地操作模型,所有输出直观可见:

>>>from hello.modelsimportPost>>># 创建两条帖子>>>p1=Post.objects.create(title="Django 入门",content="MTV 模式很容易理解")>>>p2=Post.objects.create(title="Python 之美",content="简洁优雅,强大无比")>>>>>># 查询所有帖子>>>posts=Post.objects.all()>>>print(posts)<QuerySet[<Post: Django 入门>,<Post: Python 之美>]>>>>>>># 过滤查询>>>p=Post.objects.get(id=1)>>>print(p.title, p.created_at)Django 入门2026-05-1310:40:22.123456>>>>>># 修改和保存>>>p.content="MTV 模式真的很容易理解!">>>p.save()>>>>>># 链式查询打印>>>forpostinPost.objects.filter(title__contains='Django'):... print(f"帖子:{post.title},创建于 {post.created_at}")... 帖子:Django 入门,创建于2026-05-1310:40:22.123456>>>>>>exit()

shell 的输出就是最好的老师。你可以在真正写视图之前,先用 shell 验证查询逻辑,观察返回的数据结构,确保思路正确。

5.4 编写视图:查询数据并添加控制台日志

更新hello/views.py,加入显示帖子列表的视图:

from django.shortcutsimportrender from django.httpimportHttpResponse from datetimeimportdatetime from .modelsimportPost def say_hello(request): print(f"[{datetime.now()}] say_hello 视图被访问了!")returnHttpResponse("Hello, World! 你好,世界!")def post_list(request):# 从数据库取回所有帖子posts=Post.objects.all().order_by('-created_at')print(f"[{datetime.now()}] 查询到 {len(posts)} 条帖子")# 控制台日志# 传递数据给模板渲染returnrender(request,'hello/post_list.html',{'posts':posts})

5.5 创建模板:让数据穿上 HTML 的外衣

hello/目录下创建templates/hello/两级目录(命名空间约定:应用名/模板名),新建post_list.html

<!DOCTYPE html><html><head><metacharset="utf-8"><title>博客列表</title></head><body><h1>帖子列表</h1><ahref="/hello/">返回 Hello</a><hr>{%forpostinposts %}<divstyle="margin-bottom:20px;"><h2>{{post.title}}</h2><small>{{post.created_at|date:"Y-m-d H:i"}}</small><p>{{post.content|truncatewords:30}}</p></div>{% empty %}<p>还没有帖子。</p>{% endfor %}</body></html>

这里出现了 Django 模板语法:

  • {% for post in posts %}循环

  • {{ post.title }}变量输出

  • |date|truncatewords过滤器

5.6 添加 URL 映射

编辑hello/urls.py,增加新路由:

urlpatterns=[path('', views.say_hello,name='hello'), path('posts/', views.post_list,name='post_list'),]

现在访问http://127.0.0.1:8000/hello/posts/,你会看到一个帖子列表页面。同时控制台输出:

[2026-05-1310:45:01]查询到2条帖子[13/May/202610:45:01]"GET /hello/posts/ HTTP/1.1"200512

如果我们在 shell 中再多创建几条帖子,页面会动态更新,控制台日志也会随之变化。这就是 MTV 模式的完整协作:

  1. 浏览器发起请求

  2. URL 配置匹配到post_list视图

  3. 视图调用Model(Post.objects.all()) 从数据库获取数据

  4. 视图将数据包装为上下文字典

  5. 视图调用render()选择Template渲染出 HTML

  6. 返回响应给浏览器

5.7 进阶调试:在视图中打印请求详情

对于进阶开发者,理解请求对象能帮助我们排错和扩展功能。在post_list视图中添加更详细的日志:

def post_list(request): print("="*40)print(f"请求路径: {request.path}")print(f"请求方法: {request.method}")print(f"GET 参数: {request.GET}")print(f"用户: {request.user}")print(f"User-Agent: {request.META.get('HTTP_USER_AGENT')}")posts=Post.objects.all().order_by('-created_at')print(f"查询到帖子数: {posts.count()}")print("="*40)returnrender(request,'hello/post_list.html',{'posts':posts})

访问页面后,控制台输出:

========================================请求路径: /hello/posts/ 请求方法: GET GET 参数:<QueryDict:{}>用户: AnonymousUser User-Agent: Mozilla/5.0(Macintosh;Intel Mac OS X 10_15_7)... 查询到帖子数:2========================================

甚至你可以尝试带参数访问:http://127.0.0.1:8000/hello/posts/?debug=true,控制台就会显示GET 参数: <QueryDict: {'debug': ['true']}>。这对于理解中间件、用户认证和请求流非常有益。


6. MTV 模式 vs MVC 的误解,及 Django 的“智能”调度

很多人刚学 Django 时会听到 “Django 是 MVC 框架”,但官方文档称它为 MTV。其实对应关系很简单:

Django 把“控制器”的部分逻辑分散给了框架自身的 URL 分发器和视图函数。因此,Django 视图更像一个控制器,而模板才是真正的“视图”。只要记住:视图选择并返回数据,模板渲染数据,这个弯就转过来了。

Django 的请求处理流程(从新手到进阶都应印在脑子里):

浏览器 → Nginx/WSGI → Django 中间件栈 → URL 路由匹配 → 视图函数(可调用模型)→ 加载模板 → 渲染 → HTTP 响应 → 中间件栈反向处理 → 返回浏览器

开发服务器runserver帮我们简化了前面的环节,但中间件、路由、视图这一套逻辑始终一致。


7. 更多控制台输出实例:感知 Django 的生命周期

7.1 观察 SQL 日志

settings.py中,可以添加日志配置,让所有数据库查询打印到控制台:

LOGGING={'version':1,'handlers':{'console':{'class':'logging.StreamHandler',},},'loggers':{'django.db.backends':{'handlers':['console'],'level':'DEBUG',},},}

重启服务器,再次访问帖子列表页,控制台会多出:

(0.001)SELECT"hello_post"."id","hello_post"."title",... FROM"hello_post"ORDER BY"hello_post"."created_at"DESC;args=()

这能帮助我们分析 N+1 查询问题,是进阶优化的必备技能。

7.2 利用manage.py shell_plus(需安装 django-extensions)

进阶用户推荐安装django-extensions,其提供的shell_plus会自动导入所有模型,并支持自动补全:

$ pipinstalldjango-extensions $# 在 settings.py INSTALLED_APPS 添加 'django_extensions'$ python manage.py shell_plus# Shell Plus Model Imports...from hello.modelsimportPost...>>>Post.objects.create(title='快速测试',content='自动导入超方便')<Post: 快速测试>

输出会列出所有自动导入的模块,让你能立刻开始操作。


8. 结语:从 Hello World 到掌控全局

通过这篇文章,你不仅得到了一个可运行的 Django 环境,更亲手搭建了一个包含控制台日志、数据库查询、模板渲染的 MTV 完整示例。我们从“环境搭建”开始,用django-admin startprojectstartapp命令搭起骨架;利用runserverprint在终端观察请求动态;深度剖析每个文件职责;最终在 MTV 模式下,用 Model + View + Template 实现了动态帖子列表。

给新手的建议:不要跳过控制台输出。每当迷惑时,就在视图里加一行print(request.__dict__)或查看 SQL 日志。Django 的透明性是它的优点,控制台就是你的解剖台。

给进阶者的提醒:你已看到 MTV 的完整链路,可以进一步尝试中间件编程、类视图、基于类的通用视图,甚至深入研究 ASGI 异步视图。但无论技术栈如何变迁,理解请求如何流经项目结构,始终是解决问题的基础。

Django 的第一声 “Hello, World” 只是开始,愿你在接下来的开发中,每一个print都能为你照亮前行的路。还可以去公众号、今日头条搜索「IT策士」,一起升级 IT 思维 !

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

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

立即咨询