
文章目录
📖 开篇导读
在上一节课中,我们学习了 Flask——一个轻量级的 Web 框架。它灵活、简单,适合小型应用和微服务。但当你需要构建一个功能完善的大型网站时,你可能需要用户认证、管理后台、表单处理、数据库 ORM、路由分发等功能,如果从零开始用 Flask 组装这些组件,工作量会很大。
这时候,Django 就派上了用场。Django 是一个“大而全”的 Web 框架,它遵循“电池内置”哲学,自带了许多常用模块:ORM、模板引擎、表单、认证、管理后台、缓存、国际化等。使用 Django 可以快速开发功能完备的 Web 应用,而且代码结构统一,非常适合团队协作。
💡 工作场景:
- 内容管理系统(CMS):如新闻网站、博客平台。
- 电子商务网站:Django 的 ORM 和管理后台能快速搭建商品、订单管理。
- 社交平台:用户认证、消息系统、权限控制。
- 数据分析平台:结合 Django 后台展示分析结果。
本课将带领你入门 Django,重点学习:
- Django 安装与项目创建
- 应用(App)的概念与创建
- 模型(Model):定义数据表结构
- 数据库迁移(Migration):自动生成数据库表
- Django 自带的后台管理系统(Admin)
- 视图(View)与 URL 配置
- 模板(Template)快速渲染
学完本课,你将能快速搭建一个带后台管理的数据驱动网站。
🎯 学习目标
| 目标编号 | 具体掌握内容 | 对应面试/工作价值 |
|---|---|---|
| 1️⃣ | 安装 Django,创建项目和应用 | 环境搭建 |
| 2️⃣ | 理解 Django 的 MTV 架构(Model-Template-View) | 框架设计思想 |
| 3️⃣ | 定义 模型类,使用 ORM 操作数据库 | 面向对象方式操作数据库 |
| 4️⃣ | 掌握数据库迁移流程(makemigrations/migrate) | 版本管理数据表 |
| 5️⃣ | 使用 Django Admin 管理后台,快速管理数据 | 开发效率利器 |
| 6️⃣ | 配置 URL 路由和视图函数,渲染模板 | 完成一个简单页面 |
🔥 面试考点:“Django 和 Flask 的区别?”“什么是 ORM?Django 中如何使用?”“Django 的迁移命令有哪些?”“如何注册模型到 admin 后台?”
📚 知识点理论精讲
一、Django 简介
1.1 Django 的特点
- 重量级:自带大量功能,无需从头组装。
- ORM:对象关系映射,用 Python 类操作数据库。
- MTV 模式:Model(模型)、Template(模板)、View(视图),类似于 MVC。
- 自动 Admin:根据模型自动生成增删改查后台。
- 安全性:防止 SQL 注入、XSS、CSRF 等常见攻击。
- 可扩展性:支持中间件、信号、第三方应用。
1.2 安装 Django
pip install django
验证安装:
python -m django --version
二、创建项目与应用
2.1 创建项目
django-admin startproject mysite
项目结构:
mysite/
manage.py # 命令行工具
mysite/
__init__.py
settings.py # 配置
urls.py # 根URL路由
wsgi.py # 部署入口
2.2 创建应用
Django 项目由多个应用(App)组成。一个应用是一个功能模块,例如用户、博客、留言板。
cd mysite
python manage.py startapp blog
应用结构:
blog/
migrations/ # 数据库迁移文件
__init__.py
admin.py # 注册模型到 admin
apps.py # 应用配置
models.py # 数据模型
tests.py
views.py # 视图函数
2.3 注册应用
在 mysite/settings.py 的 INSTALLED_APPS 中添加 'blog':
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
...
'blog', # 添加自定义应用
]
三、模型(Model):定义数据表
3.1 编写模型类
在 blog/models.py 中定义一个文章模型:
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200) # 标题
content = models.TextField() # 内容
created_at = models.DateTimeField(auto_now_add=True) # 创建时间
updated_at = models.DateTimeField(auto_now=True) # 更新时间
def __str__(self):
return self.title
常用字段类型:
| 字段 | 说明 |
|---|---|
CharField(max_length) | 字符串 |
TextField() | 长文本 |
IntegerField() | 整数 |
DateTimeField() | 日期时间 |
BooleanField() | 布尔值 |
ForeignKey() | 外键(一对多) |
ManyToManyField() | 多对多 |
3.2 生成数据库迁移
python manage.py makemigrations # 生成迁移文件
python manage.py migrate # 应用到数据库
Django 默认使用 SQLite,无需额外安装。
3.3 通过 ORM 操作数据
进入 Django shell:
python manage.py shell
示例:
from blog.models import Post
# 创建
p = Post(title='Hello Django', content='内容')
p.save()
# 查询所有
posts = Post.objects.all()
# 按条件查询
post = Post.objects.get(id=1)
# 更新
post.title = '新标题'
post.save()
# 删除
post.delete()
四、Django Admin 后台
Django 自带一个功能强大的管理后台,只需注册模型即可使用。
4.1 创建超级用户
python manage.py createsuperuser
按提示输入用户名、邮箱、密码。
4.2 注册模型到 admin
编辑 blog/admin.py:
from django.contrib import admin
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ('id', 'title', 'created_at', 'updated_at')
list_filter = ('created_at',)
search_fields = ('title', 'content')
4.3 启动开发服务器
python manage.py runserver
访问 http://127.0.0.1:8000/admin,登录后即可看到 Post 模型,可以添加、修改、删除数据。
🧠 类比:Django Admin 就像一个自动生成的 Excel 数据管理界面,无需编写任何 HTML。
五、视图(View)与 URL 配置
5.1 编写视图函数
在 blog/views.py 中编写返回文章列表的视图:
from django.shortcuts import render
from .models import Post
def post_list(request):
posts = Post.objects.all().order_by('-created_at')
return render(request, 'blog/post_list.html', {'posts': posts})
5.2 配置 URL
在 blog/ 下创建 urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.post_list, name='post_list'),
]
在项目级 mysite/urls.py 中包含 blog 的 URL:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')), # 所有 /blog/ 开头的路由交给 blog 处理
]
现在访问 http://127.0.0.1:8000/blog/ 会看到 post_list 视图的响应。
六、模板(Template)渲染
6.1 创建模板
在 blog/ 下创建 templates/blog/post_list.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>博客文章</title>
</head>
<body>
<h1>文章列表</h1>
{% for post in posts %}
<div>
<h2>{{ post.title }}</h2>
<p>{{ post.created_at|date:"Y-m-d H:i" }}</p>
<p>{{ post.content|truncatewords:30 }}</p>
</div>
{% empty %}
<p>暂无文章</p>
{% endfor %}
</body>
</html>
6.2 模板继承
可以创建 templates/base.html 作为基模板,其他模板继承它,减少重复代码。
<!-- base.html -->
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}我的博客{% endblock %}</title>
</head>
<body>
<div class="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
子模板:
{% extends "base.html" %}
{% block title %}文章列表{% endblock %}
{% block content %}
<!-- 列表内容 -->
{% endblock %}
七、综合案例:个人博客系统
下面将上述知识点串联起来,构建一个简单的个人博客系统,具备文章列表、文章详情、后台管理功能。
7.1 模型扩展
在 Post 模型中增加字段:author(用户名)、slug(用于 URL 的友好标识)。
from django.utils.text import slugify
class Post(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(unique=True, blank=True)
content = models.TextField()
author = models.CharField(max_length=100, default='admin')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super().save(*args, **kwargs)
def __str__(self):
return self.title
迁移更新:
python manage.py makemigrations
python manage.py migrate
7.2 文章详情视图
views.py 添加:
from django.shortcuts import get_object_or_404
def post_detail(request, slug):
post = get_object_or_404(Post, slug=slug)
return render(request, 'blog/post_detail.html', {'post': post})
URL 配置:
path('<slug:slug>/', views.post_detail, name='post_detail'),
templates/blog/post_detail.html:
{% extends "base.html" %}
{% block title %}{{ post.title }}{% endblock %}
{% block content %}
<h1>{{ post.title }}</h1>
<p>作者: {{ post.author }} | 发布于 {{ post.created_at|date:"Y-m-d H:i" }}</p>
<div>{{ post.content|linebreaks }}</div>
<p><a href="{% url 'post_list' %}">返回列表</a></p>
{% endblock %}
7.3 使用 Django Admin 管理文章
admin.py 中已经注册过,现在可以修改列表显示字段。
class PostAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('title',)} # 自动填充 slug
list_display = ('title', 'author', 'created_at')
7.4 首页改版
修改 post_list 视图,只显示文章标题和摘要,点击链接进入详情。
templates/blog/post_list.html:
{% extends "base.html" %}
{% block content %}
<h1>博客首页</h1>
{% for post in posts %}
<div>
<h2><a href="{% url 'post_detail' slug=post.slug %}">{{ post.title }}</a></h2>
<p>{{ post.created_at|date:"Y-m-d" }} by {{ post.author }}</p>
<p>{{ post.content|truncatewords:20 }}</p>
</div>
{% endfor %}
{% endblock %}
💻 代码案例实操
案例1:创建 Django 项目并用后台管理数据
# 安装 Django
pip install django
# 创建项目
django-admin startproject myblog
cd myblog
# 创建应用
python manage.py startapp article
# 编辑 settings.py,添加 article 到 INSTALLED_APPS
article/models.py:
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
pub_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
迁移并创建超级用户:
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
注册 admin:
article/admin.py:
from django.contrib import admin
from .models import Article
admin.site.register(Article)
运行服务器,访问 /admin 添加几篇文章。
案例2:显示文章列表和详情
article/views.py:
from django.shortcuts import render, get_object_or_404
from .models import Article
def article_list(request):
articles = Article.objects.all().order_by('-pub_date')
return render(request, 'article/list.html', {'articles': articles})
def article_detail(request, pk):
article = get_object_or_404(Article, pk=pk)
return render(request, 'article/detail.html', {'article': article})
article/urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.article_list, name='article_list'),
path('<int:pk>/', views.article_detail, name='article_detail'),
]
项目级 urls.py:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('articles/', include('article.urls')),
]
模板文件(位置应为 article/templates/article/)见前述示例。
案例3:使用 Django 表单创建文章(简单)
创建 article/forms.py:
from django import forms
from .models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title', 'content']
在 views.py 中添加:
from django.shortcuts import redirect
from .forms import ArticleForm
def create_article(request):
if request.method == 'POST':
form = ArticleForm(request.POST)
if form.is_valid():
form.save()
return redirect('article_list')
else:
form = ArticleForm()
return render(request, 'article/create.html', {'form': form})
article/urls.py 添加:path('create/', views.create_article, name='create_article'),
模板 create.html:
{% extends "base.html" %}
{% block content %}
<h1>新建文章</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">保存</button>
</form>
{% endblock %}
注意:Django 表单需要
{% csrf_token %}防止跨站请求伪造。
案例4:使用 ORM 查询的多种方式
# 获取所有
Article.objects.all()
# 过滤
Article.objects.filter(title__contains='Django')
# 获取单个
Article.objects.get(id=1)
# 排序
Article.objects.order_by('-pub_date')
# 限制数量
Article.objects.all()[:5]
# 链式调用
Article.objects.filter(title__icontains='python').order_by('-pub_date')
⚠️ 易错点避坑总结
| 序号 | 坑点描述 | 后果 | 解决方案 |
|---|---|---|---|
| 1 | 忘记将应用添加到 INSTALLED_APPS | 模型迁移时找不到应用 | 确保在 settings.py 中注册 |
| 2 | 模型修改后没有执行 makemigrations 和 migrate | 数据库结构与模型不一致 | 每次修改模型后执行两条命令 |
| 3 | URL 末尾忘记加斜杠导致 404 | 访问时找不到页面 | Django 默认 APPEND_SLASH,但最好自己保持一致 |
| 4 | 视图返回字符串而不是渲染模板 | 页面没有样式和布局 | 使用 render 函数 |
| 5 | 模板文件目录结构错误 | TemplateDoesNotExist | 在应用下创建 templates/appname/ 目录 |
| 6 | 忘记在模板中加载静态文件 | CSS/JS 无法加载 | 使用 {% load static %} 和 {% static 'path' %} |
| 7 | 在视图中直接操作数据库导致 N+1 查询 | 性能问题 | 使用 select_related 或 prefetch_related |
| 8 | 没有配置 ALLOWED_HOSTS 导致部署后 400 错误 | 无法访问 | 添加域名到 ALLOWED_HOSTS |
| 9 | 使用 Post.objects.get 时捕获 DoesNotExist 异常 | 对象不存在时抛出异常 | 用 get_object_or_404 或 try-except |
| 10 | 修改 slug 后旧 URL 失效 | 书签连接失效 | 可在模型中做重定向,或在修改时保留旧 slug 映射 |
📝 课后实战练习题
第1题:搭建博客项目
创建一个 Django 项目,应用名为 blog。定义 Category(分类)和 Post 模型,其中 Post 包含外键关联 Category,并包含标题、内容、发布时间。注册到 admin 后台,添加若干测试数据。
第2题:文章列表与详情
实现 blog/ 首页展示所有文章标题和发布日期,点击标题进入详情页显示完整内容。使用模板继承。
第3题:使用 Django Shell 操作数据
通过 Django shell 创建一个分类对象、三篇文章,然后查询所有属于某个分类的文章,并按发布时间逆序输出。
第4题:创建文章表单
编写一个表单,允许用户在前台提交文章(标题、内容、分类)。保存后重定向到文章列表。处理 CSRF。
第5题:标签系统(多对多)
为 Post 模型增加 tags 字段(ManyToManyField,关联 Tag 模型)。在 admin 中支持多选框,并在文章详情页显示标签。
第6题:分页功能
使用 Django 内置的分页 Paginator,在文章列表页实现分页,每页显示 5 篇文章。
第7题:简单的搜索功能
在文章列表页添加搜索框,输入关键词后,通过 GET 参数 ?q= 对标题和内容进行模糊匹配,显示搜索结果。
🔜 下节课预告
Django 和 Flask 都是 Web 开发利器。到目前为止,你已经学习了 Python 的基础、数据库、爬虫、Web 框架。下一节课我们将进入综合项目阶段,开发一个完整的个人记账系统。
第49课:综合项目一:个人记账系统全流程从零到一开发
内容包括:
- 项目需求分析与设计
- Flask(或 Django)实现后端 API
- 前端页面与交互
- 数据库设计
- 数据可视化(图表展示收支趋势)
- 用户认证
通过完整的项目实战,你将巩固前面学过的所有知识,并具备独立开发完整 Web 应用的能力。
🌟 学习鼓励:Django 的学习曲线比 Flask 陡峭,但一旦理解其设计哲学,开发效率会极高。本课只是入门,后续可以继续学习 Django 的类视图、中间件、REST framework 等。请务必动手完成全部练习,并尝试搭建自己的博客。当你看到自己编写的网站运行在服务器上时,一种成就感将油然而生。
🔗《50节课 Python 从入门到精通》系列课程导航
🌟 感谢您耐心阅读到这里!
💡 如果本文对您有所启发欢迎:
👍 点赞📌 收藏 📤 分享给更多需要的伙伴。
🗣️ 期待在评论区看到您的想法, 共同进步。
🔔 关注我,持续获取更多干货内容~
🤗 我们下篇文章见~

130

被折叠的 条评论
为什么被折叠?



