Django 实战:做一个个人博客 · 第 1 / 8 篇(展开目录)

全系列用 Django 5.2 LTS 做一个个人博客:游客看文章,作者登录后写文章,管理员维护分类和账号。Django1—Django8 是文章序号,不是 Django 版本号。

  1. Django1:起步——安装、运行与项目结构
  2. Django2:配置与路由——一个请求在 Django 里怎么走
  3. Django3:模型与迁移——把博客的数据存进数据库
  4. Django4:ORM——查询、更新、统计与事务
  5. Django5:页面——视图、模板、搜索与分页
  6. Django6:表单与后台——让作者在网页上写文章
  7. Django7:登录与权限——谁能改哪篇文章
  8. Django8:上线与维护——测试、部署、备份与发布

下载可运行的示例项目(ZIP)

约 15 分钟 · 需要 Python 3.12 或 3.13 · 全系列基于 Django 5.2 LTS

本篇目标: 在自己电脑上把博客跑起来,认识 Django 项目里每个文件的作用。

完成标志: 浏览器打开 http://127.0.0.1:8000/ 能看到页面,/admin/ 能登录后台。

1. 我们要做一个什么样的博客

整个系列做同一个项目:一个个人博客。

角色 能做什么
游客 浏览、搜索已发布的文章
作者 登录后写文章、存草稿、编辑或删除自己的文章
管理员 在后台维护分类、标签和账号

每篇文章解决一个问题:

篇 主题 解决的问题
1 起步 怎么跑起来?项目里都是什么?
2 配置与路由 一个请求在 Django 里怎么走?
3 模型与迁移 数据怎么存进数据库?
4 ORM 怎么查询、更新、统计?
5 页面 怎么把数据变成网页?
6 表单与后台 作者怎么在网页上写文章?
7 登录与权限 谁能改哪篇文章?
8 上线与维护 怎么测试、部署、备份?

2. 两条路线,选一条

  • 路线 A:从零创建。 适合想一步步看着项目长出来的读者。之后每篇按文章添加代码。
  • 路线 B:直接运行完整示例。 适合想先看成品、再回头读原理的读者。下载本页顶部目录里的 ZIP 即可。

两条路线不要混用

已经复制完整示例的,不要再运行 startproject 和 startapp,它们会覆盖已有文件。

路线 A:从零创建最小项目

macOS / Linux:

python3 --version
mkdir django-blog
cd django-blog
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install 'Django>=5.2,<5.3'
python -m django --version
python -m django startproject config .
python manage.py startapp blog
python manage.py migrate
python manage.py runserver 127.0.0.1:8000

Windows PowerShell 把创建和激活环境换成:

py -3.12 -m venv .venv
.\.venv\Scripts\Activate.ps1

如果提示脚本被禁止运行,可以不激活,直接用 .\.venv\Scripts\python.exe 代替后面的 python。

逐条看看这些命令做了什么:

命令 作用
python3 -m venv .venv 创建虚拟环境,让这个项目的依赖和别的项目隔开
pip install 'Django>=5.2,<5.3' 安装 5.2 系列的最新版本
startproject config . 创建项目骨架。末尾的点表示建在当前目录,不再多套一层
startapp blog 创建一个名为 blog 的应用
migrate 建立 Django 自带功能(用户、会话等)需要的表
runserver 启动开发服务器

打开 http://127.0.0.1:8000/,看到 Django 的欢迎页就成功了。按 Ctrl+C 停止服务器。

路线 B:直接运行完整博客

解压示例 ZIP,进入其中的 django-series/example/ 目录(也就是 manage.py 所在目录):

python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver 127.0.0.1:8000

createsuperuser 会让你设置管理员的用户名、邮箱和密码。输入密码时屏幕不显示字符,这是正常的。

启动后逐个打开这些地址检查:

地址 应该看到
/ “最新文章”页面,第一次是空的
/healthz/ {"status": "ok"}
/admin/ 后台登录页
/accounts/login/ 网站的作者登录页
/my/posts/ 未登录时自动跳到登录页

试着发第一篇文章: 登录 /admin/,新建分类“技术”和标签“Django”;回到网站首页点“写文章”,填写标题、英文网址标识(如 hello-django)和正文,状态选“已发布”,保存。回到首页就能看到它。

3. 项目里都有什么

Django 把网站分成两层:

  • 项目(project):一个能独立运行的网站,管全站配置。本例叫 config。
  • 应用(app):网站里一块相对独立的功能。本例的 blog 负责文章、分类、标签。以后加商城,就再建一个 shop 应用,不用新建项目。
django-blog/
├── manage.py            执行管理命令的入口
├── config/              项目:全站配置
│   ├── settings.py      所有配置项(第 2 篇)
│   ├── urls.py          总路由(第 2 篇)
│   ├── wsgi.py          部署时服务器加载应用的入口(第 8 篇)
│   └── asgi.py          异步部署入口,本系列不用
├── blog/                应用:博客功能
│   ├── models.py        数据模型(第 3 篇)
│   ├── views.py         处理请求(第 5、6 篇)
│   ├── urls.py          博客的路由(第 2 篇)
│   ├── forms.py         表单(第 6 篇)
│   ├── admin.py         后台配置(第 6 篇)
│   └── tests.py         测试(第 8 篇)
└── templates/           页面模板(第 5 篇)

后面每篇改哪个文件,看这张图就能找到。

路径约定

全系列提到的 config/settings.py、blog/views.py 等路径,都相对于 manage.py 所在目录;命令也默认在这个目录执行。

4. 本地运行和正式上线有什么不同

runserver 只用于开发:它会自动重载代码、显示详细错误,但不是为公网流量设计的。正式上线时,请求会经过更多环节:

开发时:  浏览器 → runserver → Django → SQLite

上线后:  浏览器 → Nginx(HTTPS)→ Gunicorn → Django → PostgreSQL
                    └─ 直接提供 /static/ 下的 CSS、JS
组件 职责
Nginx 处理 HTTPS、转发请求、直接返回静态文件
Gunicorn 正式的 Python 应用服务器,加载 Django
PostgreSQL 生产数据库,适合多人同时读写
Docker Compose 把以上服务一起启动、连成网络

现在只需要知道有这么一条链路。第 2–7 篇都在本地用 SQLite 开发;第 8 篇再完整讲容器化部署、HTTPS 和数据库切换。

5. 常见问题

现象 先检查
No module named django 是否激活了 .venv;pip 和 python 是否属于同一个环境
Error: That port is already in use 8000 端口被占用,换成 runserver 127.0.0.1:8001
no such table 是否执行过 python manage.py migrate
后台没有样式 开发时确认 DEBUG 为开启状态(默认就是)
浏览器打不开 终端里的服务器是否还在运行,地址是否写成了 127.0.0.1:8000

小练习

1. 不小心执行了 startproject config(没有末尾的点),会发生什么?

会得到 config/manage.py 和 config/config/settings.py 这样多一层的目录。可以删掉重来,或者以后都在外层 config/ 里执行命令。为了和本系列路径一致,建议删掉重建。

2. 想再做一个“相册”功能,应该新建项目还是应用?

新建应用:python manage.py startapp gallery,然后在 settings.py 的 INSTALLED_APPS 里注册(下一篇会讲为什么必须注册)。同一个网站的不同功能共用一个项目。