第48课:Python|Django框架基础【项目创建、模型映射与后台管理系统】

在这里插入图片描述


📖 开篇导读

在上一节课中,我们学习了 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.pyINSTALLED_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模型修改后没有执行 makemigrationsmigrate数据库结构与模型不一致每次修改模型后执行两条命令
3URL 末尾忘记加斜杠导致 404访问时找不到页面Django 默认 APPEND_SLASH,但最好自己保持一致
4视图返回字符串而不是渲染模板页面没有样式和布局使用 render 函数
5模板文件目录结构错误TemplateDoesNotExist在应用下创建 templates/appname/ 目录
6忘记在模板中加载静态文件CSS/JS 无法加载使用 {% load static %}{% static 'path' %}
7在视图中直接操作数据库导致 N+1 查询性能问题使用 select_relatedprefetch_related
8没有配置 ALLOWED_HOSTS 导致部署后 400 错误无法访问添加域名到 ALLOWED_HOSTS
9使用 Post.objects.get 时捕获 DoesNotExist 异常对象不存在时抛出异常get_object_or_404try-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 从入门到精通》系列课程导航

去订阅

🌟 感谢您耐心阅读到这里!
💡 如果本文对您有所启发欢迎:
👍 点赞📌 收藏 📤 分享给更多需要的伙伴。
🗣️ 期待在评论区看到您的想法, 共同进步。
🔔 关注我,持续获取更多干货内容~
🤗 我们下篇文章见~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Thomas.Sir

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值