开发环境:

  • Microsoft Windows 10 Enterprise LTSC [Version 10.0.19044.1586], locale zh-CN

  • Python 3.8.10

  • PyCharm 2021.2 (Professional Edition)

  • Visual Studio Code, 64-bit edition (version 1.67.2)


使用模板(Template)

Django 框架中,模板 是可以帮助开发者快速生成呈现给用户页面的工具。用于编写 html 代码,还可以嵌入模板代码转换更方便的完成页面开发,再通过在视图中 渲染 模板,将生成模板的设计实现了 业务逻辑视图 显示内容模板 的分离,一个视图可以使用任意一个模板,一个模板可以供多个视图使用。 我们可以轻松地将 Bootstrap 5 或其他前端组件框架添加到项目中, 更快地编写出漂亮的前端界面。

当前显示的页面 = 模板 + 数据,

模板分为两部分:

  • 静态页面:主要包括了CSS,HTML,JS,图片

  • 动态填充:主要是通过模板语言去动态的产生一些页面上的内容

添加模板文件

在项目的 templates 文件夹添加名为 index.html HTML文件, 打开 templates/index.html 文件, 编辑内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组织构架</title>
</head>
<body>
<h1>组织构架</h1>
{% for item in departments %}
{{ item.title }}<br>
{% endfor %}
</body>
</html>

修改视图文件

打开 users/views.py 文件, 编辑内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from .models import Department # 添加模型类的导入


def home(request):
""""
浏览器URL为 http://127.0.0.1:8000 时, 跳转到 http://127.0.0.1:8000/department/
"""
return HttpResponseRedirect('/department/')

def index(request):
# 查询所有数据(可以在之前默认后台中多添加几个组织构架数据用于显示)
departments = Department.objects.all()
# 调用并传递数据到指定的模板文件
return render(request, 'index.html', {'departments': departments})

编辑项目的路由, 自动跳转到当前应用

打开 myproject/urls.py 文件, 编辑代码如下:

1
2
3
4
5
6
7
8
9
10
11
from django.contrib import admin
from django.urls import path, include # 添加 include 的导入
import department.views

urlpatterns = [
path('admin/', admin.site.urls),
# 没有加路径时进行跳转
path('', users.views.home, name='home'),
# 添加应用的urls, department.urls: 子应用的urls 文件路径
path('department/', include('department.urls')),
]

查看模板的显示结果

在浏览器中打开URL:http://127.0.0.1:8000, 会自动跳转到 http://127.0.0.1:8000/department/

使用静态文件

静态文件 是指 CSSJavaScript字体图片或者是用来组成用户界面的任何其他资源。

实际上,Django 本身是不负责处理这些文件的,但是为了让我们的开发过程更轻松,Django 提供了一些功能来帮助我们管理静态文件。

添加静态文件夹

在项目根目录创建名为 static 的文件夹, 下载相应的资源文件后解压, 并将其中的文件复制到 static 文件夹中。

资源文件下载: https://hujiyi.github.io/2022/07/03/create-an-app-in-django-003/assets.zip

以上资源文件包含:

  • Bootstrap 5: 流行的前端开源工具包;
  • poper.js: Bootstrap5 依赖的 JavaScript 库;
  • favicon.ico: 网站图标。

解压后的文件夹结构如下图所示:

在模板中使用静态文件

添加静态文件夹配置

打开 myproject/settings.py 文件, 找到 STATIC_URL 变量, 在其下方添加配置:

1
2
3
4
# 静态文件夹
STATICFILES_DIRS = [
BASE_DIR / "static",
]

如下图所示:

使用静态文件

打开 templates/index.html 文件, 编辑内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/static/favicon.ico">
<link href="/static/bootstrap-5.1.3-dist/css/bootstrap.css" rel="stylesheet">
<title>组织构架</title>
</head>
<body>
<div class="container">
<h1>组织构架</h1>
<ul class="list-group">
{% for item in departments %}
<li class="list-group-item"> {{ item.title }}</li>
{% endfor %}
</ul>
</div>
<script src="/static/poper/popper.min.js"></script>
<script src="/static/bootstrap-5.1.3-dist/js/bootstrap.js"></script>
</body>
</html>

结果预览

基于 Bootstrap5 的整体布局

创建布局模板母版页

在项目的 templates 文件夹添加名为 layout.html HTML文件, 编辑内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="{% static 'favicon.ico' %}">
<link href="{% static 'bootstrap-5.1.3-dist/css/bootstrap.css' %}" rel="stylesheet">
<title>{% block title %}{% endblock %}</title>
{% block style %}{% endblock %}
</head>
<body>
<div class="d-flex flex-column vh-100">
{% block content %}
{% endblock %}
</div>
<script src="{% static 'poper/popper.min.js' %}"></script>
<script src="{% static 'bootstrap-5.1.3-dist/js/bootstrap.js' %}"></script>
<!-- 用于添加 javascript -->
{% block scripts %}{% endblock scripts %}
</body>
</html>

模板 最前面 使用了 Static Files App 模板标签 {% load static %}, 加载 静态文件 变量

模板标签 {% static %} 用于构成资源文件完整URL, {% static 'bootstrap-5.1.3-dist/css/bootstrap.css' %} 将返回 /static/bootstrap-5.1.3-dist/css/bootstrap.css, 完整的路径相当于 http://127.0.0.1:8000/static/bootstrap-5.1.3-dist/css/bootstrap.css

{% static %}模板标签使用 myproject/settings.py 文件中的 STATIC_URL 配置来组成最终的 URL

{% block <名字> %} {% endblock %} 用于在模板中保留一个空间,一个”子”模板(继承这个母版页的模板)可以在这个空间中插入代码和 HTML; 上面的模板文件中共定义了四个保留空间, contenttitlestylescripts 为不同保留空间的名字

添加网站导航栏

新建HTML文件 templates/nav.html, 编辑内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!-- 导航菜单栏 -->
<nav class="navbar navbar-expand-sm bg-light mb-4">
<div class="container d-flex w-100">
<h2>我的网站</h2>
<div class="flex-grow-1"></div>
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="#">首页</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/users/">组织构架管理</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">当前用户: </a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">注销 </a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">登录</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">注册</a>
</li>
</ul>
</div>
</nav>

参考资料URL: https://www.bootstrap.cn/doc/read/146.html

添加网站底部内容文件

新建HTML文件 templates/footer.html, 编辑内容如下:

1
2
<!-- 网站页脚 -->
<footer class="text-center mt-5 p-3 bg-secondary"> 版权所有</footer>

继承复用模板

在项目的 templates 文件夹中新建名为 department 的新文件夹, 将 templates/index.html 移动到 templates/department/ 文件夹中。

打开 移动位置后templates/department/index.html 文件, 编辑内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{% extends "layout.html" %}

{% block title %}组织构架{% endblock %}

{% block content %}
{% include "nav.html" %}
<div class="container flex-grow-1">
<h1>组织构架</h1>
<ul class="list-group">
{% for item in departments %}
<li class="list-group-item"> {{ item.title }}</li>
{% endfor %}
</ul>
</div>

{% include "footer.html" %}
{% endblock %}

第一行的 {% extends "layout.html" %} 表示要使用 layout.html 作为母版页(继承)

{% block title %}组织构架{% endblock %} 表示在母版页名字为 title 的保留空间放置内容。{% block content %} {% endblock %}作用相同

{% include "nav.html" %}{% include "footer.html" %} 表示分别在该位置插入nav.htmlfooter.html 文件中的内容

编辑视图文件

1
2
3
4
5
6
7
8
9
from django.shortcuts import render
# from django.http import HttpResponse
from .models import Department


def index(request):
departments = Department.objects.all()
# 修改模板文件为: 'departments/index.html'
return render(request, 'department/index.html', {'departments': departments})

结果预览

使用表格显示组织构架

打开 templates/department/index.html 文件, 编辑内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
{% extends "layout.html" %}

{% block title %}组织构架{% endblock %}

{% block content %}
{% include "nav.html" %}
<div class="container flex-grow-1">
<h1>组织构架</h1>

<table class="table table-striped table-hover">
<thead>
<tr>
<th>ID</th>
<th>名称</th>
<th>类别</th>
<th>所属</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for item in departments %}
<tr class="align-middle">
<td>{{ item.id }}</td>
<td>{{ item.title }}</td>
<td>
{# get_type_display: 显示 type 字段的 choices 的名字 #}
{{ item.get_type_display }}
{# {% if item.type == 'department' %} #}
{# 部门 #}
{# {% else %} #}
{# 公司 #}
{# {% endif %} #}
</td>
<td>{{ item.parent.title }}</td>
<td width="120px">
<button type="button" class="btn btn-sm btn-outline-primary">编辑</button>
<button type="button" class="btn btn-sm btn-outline-danger">删除</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

{% include "footer.html" %}
{% endblock %}

结果预览

参考资料:

  1. Django v4.0 中文文档

  2. Django入门与实践教程

  3. Bootstrap5 中文手册

===END===