开发环境:
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
或其他前端组件框架添加到项目中, 更快地编写出漂亮的前端界面。
当前显示的页面
= 模板
+ 数据
,
模板分为两部分:
添加模板文件
在项目的 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 import department.views
urlpatterns = [ path('admin/', admin.site.urls), path('', users.views.home, name='home'), path('department/', include('department.urls')), ]
|
查看模板的显示结果
在浏览器中打开URL:http://127.0.0.1:8000
, 会自动跳转到 http://127.0.0.1:8000/department/
使用静态文件
静态文件
是指 CSS
,JavaScript
,字体
,图片
或者是用来组成用户界面的任何其他资源。
实际上,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>
{% 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; 上面的模板文件中共定义了四个保留空间, content
、title
、style
和 scripts
为不同保留空间的名字
添加网站导航栏
新建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.html
和 footer.html
文件中的内容
编辑视图文件
1 2 3 4 5 6 7 8 9
| from django.shortcuts import render
from .models import Department
def index(request): departments = Department.objects.all() 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 %}
|
结果预览
参考资料:
Django v4.0 中文文档
Django入门与实践教程
Bootstrap5 中文手册
===END===