Django 入门教程:从零开始开发 Web 应用2
2025年10月10日 00:38
六、模板(Templates):如何展示动态内容?
1. 什么是模板?为什么需要它?
模板是包含 HTML 代码和特殊模板语法的文件,用于生成动态网页。它的作用是:
- 分离 HTML 代码和 Python 代码,使前后端分离
- 可以重用 HTML 结构(如导航栏、页脚)
- 支持动态内容替换,根据不同数据展示不同内容
2. 模板的工作原理
Django 模板系统的工作流程:
- 视图函数准备好需要展示的数据
- 视图函数调用
render()函数,指定模板文件和数据 - Django 模板引擎加载模板文件,替换其中的模板变量和标签
- 生成最终的 HTML,返回给用户
3. 创建模板文件
Django 推荐的模板存放结构是在应用目录下创建
templates文件夹,再在里面创建与应用同名的文件夹(避免模板名冲突)。- 在
blog目录下创建templates文件夹 - 在
templates文件夹下创建blog文件夹 - 在
blog文件夹下创建home.html文件:
html
预览
<!-- blog/templates/blog/home.html -->
<!DOCTYPE html>
<html>
<head>
<title>我的博客</title>
</head>
<body>
<h1>欢迎来到我的博客!</h1>
<p>今天是:{{ today }}</p>
</body>
</html>
{{ today }}是模板变量,会被视图传递的实际数据替换
4. 在视图中使用模板
修改
blog/views.py,使用模板展示动态内容:python
运行
from django.shortcuts import render
from datetime import datetime
def home(request):
# 准备要传递给模板的数据
context = {
'today': datetime.now().strftime('%Y年%m月%d日'),
}
# render()函数会加载模板,替换变量,并返回HttpResponse
return render(request, 'blog/home.html', context)
render()函数的三个参数:request:请求对象- 模板路径(
blog/home.html对应blog/templates/blog/home.html) context:一个字典,包含要传递给模板的数据
现在访问
http://127.0.0.1:8000/blog/,你会看到当前日期被动态显示出来。5. 模板继承:避免重复代码
模板继承可以让你创建一个基础模板,然后在其他模板中重用它,避免重复编写相同的 HTML 代码(如导航栏、页脚)。
- 创建基础模板
blog/templates/blog/base.html:
html
预览
<!-- blog/templates/blog/base.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}我的博客{% endblock %}</title>
</head>
<body>
<header>
<h1><a href="{% url 'blog_home' %}">我的博客</a></h1>
<nav>
<a href="{% url 'blog_home' %}">首页</a>
</nav>
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
<p>© {% now "Y" %} 我的博客</p>
</footer>
</body>
</html>
{% block 名称 %}:定义一个可被继承模板覆盖的块{% url 'blog_home' %}:使用 URL 的名称生成 URL,避免硬编码
- 修改
home.html继承基础模板:
html
预览
<!-- blog/templates/blog/home.html -->
{% extends 'blog/base.html' %}
{% block title %}首页 - 我的博客{% endblock %}
{% block content %}
<h2>欢迎来到我的博客!</h2>
<p>今天是:{{ today }}</p>
{% endblock %}
{% extends %}:指定要继承的基础模板- 只需要填充
block中的内容,其他部分会自动继承
七、模型(Models):如何存储和管理数据?
1. 什么是模型?为什么需要它?
模型是 Django 中用于表示数据库表的 Python 类。它的作用是:
- 定义数据的结构和类型
- 提供数据库操作的方法,无需编写 SQL
- 实现数据验证和业务逻辑
Django 的 ORM(对象关系映射)系统会自动将模型转换为数据库表,将模型的属性转换为表的字段。
2. 创建第一个模型
我们来创建一个
Article模型,表示博客文章:编辑
blog/models.py:python
运行
from django.db import models
from django.utils import timezone
class Article(models.Model):
# 文章标题,最大长度100
title = models.CharField(max_length=100)
# 文章内容,长文本
content = models.TextField()
# 发布时间,默认为当前时间
published_time = models.DateTimeField(default=timezone.now)
# 定义对象的字符串表示
def __str__(self):
return self.title
这个模型会在数据库中创建一个名为
blog_article的表,包含title、content和published_time三个字段。3. 模型字段类型详解
Django 提供了多种字段类型,用于存储不同类型的数据:
- CharField:短文本字段python运行
title = models.CharField(max_length=100) # 必须指定max_length - TextField:长文本字段,用于存储大量文本python运行
content = models.TextField() - DateTimeField:日期时间字段python运行
# auto_now_add: 创建时自动设置为当前时间,之后不会改变 created_time = models.DateTimeField(auto_now_add=True) # auto_now: 每次保存时自动更新为当前时间 updated_time = models.DateTimeField(auto_now=True) # default: 设置默认值 published_time = models.DateTimeField(default=timezone.now) - DateField:日期字段(只包含年、月、日)python运行
birthday = models.DateField() - TimeField:时间字段(只包含时、分、秒)python运行
meeting_time = models.TimeField() - IntegerField:整数字段python运行
age = models.IntegerField() - FloatField:浮点数字段python运行
weight = models.FloatField() - DecimalField:高精度小数字段,适合存储货币等需要精确计算的数据python运行
price = models.DecimalField(max_digits=10, decimal_places=2)max_digits:总位数decimal_places:小数位数
- BooleanField:布尔值字段(True/False)python运行
is_published = models.BooleanField(default=False) - EmailField:电子邮件字段,会自动验证格式python运行
email = models.EmailField() - URLField:URL 字段,会自动验证格式python运行
website = models.URLField() - ForeignKey:外键,用于建立多对一关系python运行
# 假设我们有一个Category模型 category = models.ForeignKey('Category', on_delete=models.CASCADE)on_delete=models.CASCADE:当关联的对象被删除时,该对象也被删除
- ManyToManyField:多对多关系python运行
tags = models.ManyToManyField('Tag')
4. 数据库迁移:将模型同步到数据库
修改模型后,需要执行 "迁移" 操作,将模型的变化同步到数据库中。
- 生成迁移文件:bash
python manage.py makemigrations这会在blog/migrations目录下生成一个迁移文件,记录模型的变化。 - 应用迁移:bash
python manage.py migrate这会执行迁移文件中的 SQL 语句,实际修改数据库。
每次修改模型(添加字段、修改字段类型等)后,都需要执行这两个命令。
八、管理界面:快速管理你的数据
Django 提供了一个自动生成的管理界面,让你可以轻松管理数据库中的数据。
1. 创建超级用户
首先需要创建一个管理员账号:
bash
python manage.py createsuperuser
按照提示输入用户名、电子邮件和密码(密码输入时不会显示)。
2. 注册模型到管理界面
编辑
blog/admin.py,将Article模型注册到管理界面:python
运行
from django.contrib import admin
from .models import Article
# 注册Article模型
admin.site.register(Article)
3. 自定义管理界面
可以自定义模型在管理界面中的显示方式:
python
运行
from django.contrib import admin
from .models import Article
class ArticleAdmin(admin.ModelAdmin):
# 列表页显示的字段
list_display = ('title', 'published_time')
# 可搜索的字段
search_fields = ('title', 'content')
# 过滤条件
list_filter = ('published_time',)
# 注册模型和自定义类
admin.site.register(Article, ArticleAdmin)
4. 使用管理界面
启动开发服务器,访问
http://127.0.0.1:8000/admin/,使用你创建的超级用户登录。你可以:
- 点击 "Articles" 进入文章管理页面
- 点击 "Add" 添加新文章
- 编辑或删除已有的文章
九、完善博客应用:将所有组件结合起来
让我们完善博客应用,实现文章列表和详情页功能。
1. 更新视图
修改
blog/views.py:python
运行
from django.shortcuts import render, get_object_or_404
from django.utils import timezone
from .models import Article
def home(request):
# 获取所有文章,按发布时间倒序排列
articles = Article.objects.all().order_by('-published_time')
context = {
'today': timezone.now().strftime('%Y年%m月%d日'),
'articles': articles
}
return render(request, 'blog/home.html', context)
def article_detail(request, article_id):
# 获取指定ID的文章,如果不存在则返回404错误
article = get_object_or_404(Article, pk=article_id)
context = {
'article': article
}
return render(request, 'blog/article_detail.html', context)
2. 更新 URL 配置
修改
blog/urls.py:python
运行
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='blog_home'),
# 文章详情页,<int:article_id>表示接收一个整数作为文章ID
path('article/<int:article_id>/', views.article_detail, name='article_detail'),
]
3. 创建文章详情页模板
创建
blog/templates/blog/article_detail.html:html
预览
{% extends 'blog/base.html' %}
{% block title %}{{ article.title }} - 我的博客{% endblock %}
{% block content %}
<article>
<h2>{{ article.title }}</h2>
<p class="published-time">发布时间:{{ article.published_time|date:"Y年m月d日 H:i" }}</p>
<div class="content">
{{ article.content|linebreaks }} {# linebreaks过滤器将换行符转换为<br>或<p>标签 #}
</div>
</article>
<p><a href="{% url 'blog_home' %}">返回首页</a></p>
{% endblock %}
4. 更新首页模板
修改
blog/templates/blog/home.html:html
预览
{% extends 'blog/base.html' %}
{% block title %}首页 - 我的博客{% endblock %}
{% block content %}
<h2>欢迎来到我的博客!</h2>
<p>今天是:{{ today }}</p>
<h3>最新文章</h3>
{% if articles %}
<ul class="article-list">
{% for article in articles %}
<li>
<h4>
<a href="{% url 'article_detail' article.id %}">
{{ article.title }}
</a>
</h4>
<p class="published-time">
发布时间:{{ article.published_time|date:"Y年m月d日" }}
</p>
<p class="summary">
{{ article.content|truncatechars:100 }} {# 只显示前100个字符 #}
</p>
</li>
{% endfor %}
</ul>
{% else %}
<p>暂无文章,敬请期待!</p>
{% endif %}
{% endblock %}
5. 测试完整功能
- 访问管理界面
http://127.0.0.1:8000/admin/,添加几篇测试文章 - 访问博客首页
http://127.0.0.1:8000/blog/,查看文章列表 - 点击文章标题,进入文章详情页
十、总结与下一步学习
通过本教程,你已经掌握了 Django 的核心概念和基本用法:
- 理解了 Django 的项目和应用结构
- 学会了创建视图和配置 URL 路由
- 掌握了模板的使用和继承
- 了解了模型的定义和各种字段类型
- 学会了使用管理界面管理数据
- 完成了一个简单但完整的博客应用
下一步可以学习:
- Django 表单:处理用户输入
- 用户认证:实现注册、登录功能
- 静态文件:添加 CSS、JavaScript 和图片
- 高级模型操作:复杂查询、关系处理
- 部署:将应用发布到互联网
Django 官方文档(https://docs.djangoproject.com/)是学习的最佳资源,建议深入阅读。
祝你在 Django 的学习道路上取得进步!