Django安装与测试入门:从项目结构到自动化测试核心链路

Django安装与测试入门:从项目结构到自动化测试核心链路
很多想入门 Django 的同学第一次搜索“Django 快速入门”时往往以为最难的是那条安装命令。真正开始折腾之后才发现安装本身确实不难真正拦住人的是安装完之后那一刻的茫然项目创建出来了应用也注册了开发服务器也启动了但接下来呢这种状态我见过很多次。有人卡在虚拟环境里出不来有人把django-admin和manage.py的关系搞混有人写好了视图函数却不知道为什么要配一个urls.py还有人第一次跑python manage.py test的时候发现测试框架不知道要测什么。这些都不是工具的问题而是我们对“快速入门”这件事的预期出了问题。这篇文章想换一个切入角度Django 安装与测试不只是让你跑起一个欢迎页而是让你理解这套框架的第一个核心心智模型——项目、应用、路由、测试之间是怎么样被串起来的。这个心智模型建立起来之后你后面学模型、视图、模板、ORM都会顺畅很多。1. 先搞清楚 Django 到底帮你解决了什么问题1.1 为什么不是“安装一个库”这么简单如果你只是写过一个 Flask 的接口可能会觉得 Django 也是一个库装完之后import django就能用。但实际用起来会发现Django 更像一套“自带约定的开发环境”。它帮你干掉了网站开发里那些重复性极高的部分把“接收 HTTP 请求”这个动作抽象成“路由到某个视图函数”把“操作数据库”这个动作封装成 ORM让你不直接写 SQL 就能完成建表、增删改查把“管理后台”这种几乎每个后台项目都需要的功能直接做成一个内置模块把“处理表单、校验数据、保护 CSRF”这些安全细节做成了框架层面的默认配置。所以Django 的安装不是“装个库”而是“搭建一套本地开发环境”。也正因为如此它的学习曲线不是一条从零开始慢慢上升的直线而是先爬一段坡等你理解了项目结构之后后面的路会突然变宽。1.2 从“能运行”到“能开发”之间隔着一套约定很多新手装完 Django运行python manage.py runserver看到那个火箭欢迎页觉得已经成功了。但从工程角度这只能说明你的环境没坏Django 能启动。真正能开发意味着你理解了三样东西项目的入口在哪settings.py是配置中心urls.py是请求入口。应用和项目的关系一个项目可以包含多个应用一个应用是可以被复用的业务模块。代码是怎么被调用的用户访问 URL →urls.py匹配路由 → 调用对应的视图函数 → 视图返回一个响应。这三点就是贯穿 Django 开发最核心的主干。安装和测试实际上就是在建立这套主干。2. 开始之前需要想清楚的三件事2.1 Python 版本与 Django 版本的捆绑关系Django 是一个对 Python 版本有明确要求的框架。不同版本的 Django对应的 Python 版本不同。安装之前先确认这一点后面能少踩很多坑。简单来说如果你用的是 Python 3.10那选择 Django 4.2 LTS 基本不会出问题如果是 Python 3.12那建议直接考虑 Django 5.x。这里有一个很实际的经验一般建议优先选择 LTS 版本也就是长期支持版本。不是因为新功能不重要而是因为教程、第三方库、常见报错解决方案都集中在 LTS 版本上。确定版本这件事可以放在安装之前。别一上来就pip install django然后拉到最新版最新版不一定是坑但一旦遇到兼容问题你排查起来会非常煎熬。2.2 不要跳过虚拟环境“我直接在全局环境里装不行吗”行但很容易把自己坑了。Django 项目对依赖版本非常敏感。你今天用 Django 4.2 写好的项目明年换台新电脑全局 Python 环境里装的是 Django 5.2项目跑起来可能直接报一堆兼容性错误。虚拟环境的价值就是把每个项目的依赖“锁”在自己的环境里互不污染。用 Python 自带的方式创建虚拟环境是最稳妥的python -m venv myenv在 Windows 下激活myenv\Scripts\activate在 macOS 或 Linux 下激活source myenv/bin/activate激活成功之后命令行前面会出现(myenv)这个标识后续安装的包都会进到这个环境里。2.3 用 pip 装还是用官方推荐装Django 的官方文档推荐使用pip安装这也是最常见的安装方式。安装命令只有一行pip install django4.2.16这里的4.2.16是版本号。不加版本号直接装也是可以的会拉到目前 PyPI 上的最新稳定版但很多时候你不知道最新版是什么那就失去了对运行环境的控制。装完之后可以验证一下python -m django --version如果这条命令正常输出版本号说明 Django 已经安装成功。注意这里最好用python -m django而不是直接敲django-admin前者能更明确地受当前虚拟环境控制不会一不小心调到全局环境里。3. 最小可用流程从安装到页面返回一个响应3.1 创建项目理解 startproject 做了什么安装完成之后第一步不是急着打开 IDE 写代码而是创建项目。创建项目用下面这条命令django-admin startproject mysite这里需要理解一个重要区别django-admin是 Django 的命令行工具专门用于创建和管理项目而manage.py是生成在项目内部的脚本后续对项目的管理操作比如启动服务、执行迁移、运行测试基本都用它。创建完之后你会在目录里看到这样的结构mysite/ manage.py mysite/ __init__.py settings.py urls.py asgi.py wsgi.py外层mysite是项目容器里层mysite是项目配置文件所在包。settings.py是全局配置urls.py是全局路由入口。这两个文件是你前期接触最多的文件。3.2 创建应用项目是容器应用才是业务很多初学者第一次搞混的就是启动项目之后为什么要在业务代码里创建一个应用这里用一句话说清楚项目负责配置应用负责干活。你写用户管理、博客文章、订单处理这些都属于具体业务应该放在各自的应用里。一个项目可以包含多个应用应用之间相互独立也是一种可复用模块。创建应用python manage.py startapp blog你会看到多出blog/目录里面包括views.py、models.py、migrations/等文件。现在还不急着写业务代码先把应用注册进项目。打开mysite/settings.py在INSTALLED_APPS列表里加上blogINSTALLED_APPS [ django.contrib.admin, django.contrib.auth, django.contrib.contenttypes, django.contrib.sessions, django.contrib.messages, django.contrib.staticfiles, blog, ]这个注册动作很关键。Django 只有知道你的应用存在才会在建表、跑迁移、执行测试时把你应用的模型纳入管理。3.3 写第一个视图让页面有真正的输出打开blog/views.py定义一个最简单的视图函数from django.http import HttpResponse def index(request): return HttpResponse(Hello, Django.)这个视图函数表示当用户访问对应 URL 时返回一段字符串。接下来需要把 URL 和视图函数关联起来。在blog应用目录下新建urls.py写入from django.urls import path from . import views urlpatterns [ path(, views.index, nameindex), ]但这样还不够。Django 项目的主路由在mysite/urls.py里需要把这个应用的子路由挂载上去。修改mysite/urls.pyfrom django.contrib import admin from django.urls import path, include urlpatterns [ path(admin/, admin.site.urls), path(, include(blog.urls)), ]这就是写 Django 页面必经的一整套链路URL → 匹配路由 → 调用视图 → 返回响应。第一次手动完成这个链路比看任何教程都更有感知。3.4 启动开发服务器并验证启动服务器只需要一行命令python manage.py runserver默认监听本机 8000 端口浏览器访问http://127.0.0.1:8000/如果页面显示Hello, Django.说明从安装到视图的最小链路已经跑通了。这里有一个很容易忽略的细节runserver是开发服务器不是生产服务器。它的作用是提供热重载和友好的错误页面方便本地调试。千万不要把它直接部署到线上。4. 第一次测试别只“能跑通”要验证核心链路4.1 为什么开发服务器启动不等于应用正确很多人的测试体验停留在“页面能打开就行”。但在 Django 里测试的意义不是看页面能不能打开而是用自动化方式验证“某个输入对应某个输出”。这就像你写了一个计算器手动按 11 发现等于 2这只能说明当前这步操作没出错。但代码改动之后如何确定历史功能没有被破坏这时候就需要回归测试。Django 自带的测试框架基于 Python 标准库的unittest几乎不需要额外配置。4.2 写一个最基础的自动化测试打开blog/tests.py写入以下内容from django.test import TestCase from django.urls import reverse class IndexViewTests(TestCase): def test_index_returns_hello(self): response self.client.get(reverse(index)) self.assertEqual(response.status_code, 200) self.assertContains(response, Hello, Django.)解释一下这段代码在测试什么self.client.get(...)是 Django 内置测试客户端它会模拟一次 HTTP GET 请求reverse(index)会根据 URL 名称反推出 URL 路径assertEqual检查响应状态码是不是 200assertContains检查响应内容是否包含指定字符串。这看起来只是验证了一个最简单的视图但它建立了一个非常重要的习惯写代码时先想清楚验收标准是什么然后用测试去固化这个标准。4.3 运行测试并理解结果运行测试命令python manage.py test如果一切正常终端输出会类似Found 1 test(s). Creating test database for alias default... System check identified no issues (0 silenced). . ---------------------------------------------------------------------- Ran 1 test in 0.012s OK注意到“Creating test database for alias default”这一行。Django 测试时不会动你现有的开发数据库它会创建一个临时数据库测试结束后销毁。这也是为什么 Django 能放心地让你在本地跑测试——它不会破坏已有数据。如果你把测试改成失败用例比如期望响应包含Hello, World就会看到FAILED并告诉你断言失败的具体位置。这种“红绿切换”的反馈循环才是自动化测试真正有价值的地方。第一次做 Django 测试先不要追求覆盖率和复杂测试用例。先确认“测试框架能运行、用例能通过”比什么都重要。5. 新手最容易踩的坑和排查顺序安装和测试在表面上只有几条命令实际执行起来错误五花八门。我在不同环境下见过下面这些高频问题整理成一条排查链路比任何万能解决方案都实用。5.1 Django 版本与 Python 版本不匹配现象安装 Django 后运行django-admin startproject报ImportError: cannot import name xxx from django或直接提示版本不支持。原因Django 版本与 Python 版本存在兼容区间老版本的 Django 在 Python 3.12 上可能无法正常运行。处理先确认 Python 版本python --version再确认 Django 版本python -m django --version查一下官方版本兼容对照表选择合适版本重新安装。5.2 用了全局环境虚拟环境没激活现象pip install django明明成功但在项目目录里运行python manage.py却提示找不到模块。原因多半是你激活的虚拟环境不是安装 Django 的那个环境或者命令执行时用的 Python 解释器不对。处理which python which django-admin pip list | grep django确认当前环境里 Django 是否存在再决定是重新激活环境还是重新安装。5.3 端口被占用现象运行python manage.py runserver报Error: That port is already in use.处理换一个端口启动python manage.py runserver 8001或者直接指定0.0.0.0:8000先启动然后看是否有别的进程占用了本地端口。5.4 应用没有注册进 INSTALLED_APPS现象创建了应用、写了模型运行迁移命令时报错说表不存在或模型没有注册。处理回到settings.py确认INSTALLED_APPS里是否已经把应用名加进去了。Django 只有在应用注册后才会扫描应用的models.py、tests.py等文件。5.5 一个推荐的排查顺序当你遇到 Django 相关报错不要直接复制报错搜索先按下面这个顺序自查现象报错、卡住、无输出、页面白屏。输入URL 是否正确请求方式是否正确参数是否缺失。环境虚拟环境是否激活Python 版本和 Django 版本是否匹配settings.py里的应用列表是否完整。参数runserver的端口有没有冲突测试命令有没有指定 label。边界Django 版本本身有什么行为变化和教程不一致时以哪个版本为准。大部分新人问题都不是 Django 设计得不好而是环境不一致或者版本控制没做好。6. 从入门走向项目化你在学习时容易忽略的几件事6.1 先跑通再谈“优雅”很多初学者在入门阶段就开始纠结“代码是不是写得不够 Pythonic”“有没有更高级的写法”。这其实是本末倒置。Django 的入门目标应该是用最小的代码量把一条完整的请求链路跑通。这个链路越简单越好因为越简单越容易排查。你可以在views.py里直接写HttpResponse不用急着上模板你可以先不配数据库不用建模型。先把请求链路弄明白然后再逐步加入模板、模型、表单。6.2 数据库迁移的意义当你开始接触模型之后一定会频繁遇到这两条命令python manage.py makemigrations python manage.py migrate很多人会直接执行但理解它们的区别很重要makemigrations根据模型变更生成一个新的迁移文件相当于“记录这次变更”。migrate应用迁移文件把变更实际同步到数据库。这就像改代码之前先写一份变更说明然后再真正下去改。理解这一点之后你在团队协作、版本回退、上线部署时遇到迁移冲突就不会一头雾水。6.3 读官方文档的顺序Django 的官方文档非常完善但新手直接进去可能会被目录吓到。我的建议是先读这几个部分Tutorial Part 1 到 Part 4把核心链路走一遍。Writing your first Django app理解项目、应用、视图、模板、测试之间的关系。Database operations用到数据库时再回头查。不要一开始就去看 DRF、中间件、信号、缓存这些进阶主题。Django 的深度不是看出来的是用出来的。6.4 适合谁不适合谁Django 适合想用 Python 做完整的 Web 项目又不想自己搭太多基础设施团队协作开发需要统一的项目结构和惯例业务中有后台管理、数据模型、用户认证等常见需求。Django 不适合只想写一个非常简单的 API不想要太多约定对请求速度和极致性能有极高要求想完全掌控所有技术选型。如果你正处于“学过 Python 语法想做一个真正的网站”这个阶段Django 的安装与测试就是第一个最容易获得成就感的节点。很多人会在这里停留两三天不是因为难而是因为没有搞懂“跑通一个页面”和“理解请求链路”之间的区别。把它们区别清楚之后后面的路会顺很多。

最新新闻

日新闻

周新闻

月新闻