本文为 Django 学习总结,讲解模板的基本操作。
所有的代码见【Django】系列。
在 Django 简介中我们已经介绍过 Django 中我们使用 MTV 模型。其中模板是 HTML 页面,可以根据上篇讲解的视图中传过来的数据进行相应的填充。
我们创建模板时需要一个 templates 的目录,与 myApp 和 project 同级。也可以将 templates 放到 myApp 目录下,这样方便 myApp 的移植,无需修改。但工程中还是通常使用第一种方法。因为一个工程中会有多个应用,因此模板下还要对应多个应用,我们需要在 templates 目录下创建 myApp 目录(project/templates/myApp)。目录树如下:
因为 templates 目录是我们新添加的,因此需要修改 settings.py 下的 TEMPLATES
,将其中的 'DIRS': [],
修改为 'DIRS': [os.path.join(BASE_DIR), 'templates'],
,其中 BASE_DIR
指的是外层的 project 目录,其定义如下:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
我们进一步完善页面,现在希望输入 127.0.0.1:8000/grades 能显示所有班级。我们首先要在 myApp 目录下定义一个模板,即创建一个 .html 文件。我们想要如下图所示的显示方法,逐行显示我们的班级信息。
模板语法有两种,一种为**{{输出值,可以是变量或对象.属性}},另一种为{%执行代码段%}**。html 文件中循环显示班级的代码如下:
<body>
<h1>班级信息列表h1>
<ul>
{%for grade in grades%}
<li>
<a href="#">{{grade.gname}}a>
li>
{%endfor%}
ul>
body>
我们在输入 URL 后还要对其进行分发,需要在 myApp/urls.py 中添加配置,配置中还要分发一个视图,视图依旧在 myApp/views.py 中定义。关于视图定义和 URL 分发的讲解见:Django 视图的基本操作。视图要从模型中拿数据,再将数据给模板,再将模板返回。
from .models import Grades
def grades(request):
# 去模板取数据
gradesList = Grades.objects.all()
# 将数据传递给模板,模板再渲染页面,将渲染好的页面返回给浏览器
return render(request, 'myApp/grades.html', {"grades": gradesList})
其中 Grades.objects.all()
的用法见跑通 Django。然后添加 grades
的配置:re_path(r'^grades/$', views.grades)
。
这里的逻辑稍微有点复杂,没关系,我们用一张图讲明白它(重点来了!!!):
首先我们有一个需求,希望输入 127.0.0.1:8000/grades 能显示所有班级,这就要分配 URL,然而在 URL 中要返回一个视图,因此我们还要在 myApp/view.py 中定义一个视图,视图要去模型(就是个类,详细见跑通 Django)里面取数据,将数据返回给视图,视图再将要展示的数据返回给模板,模板进行渲染后返回给浏览器。最后刷新浏览器得到正确结果:
以上就是输入 URL 后从数据库取出数据的全部操作,这是 Django 的一个重点,一定要反复消化理解。如果你还是有点乱,没关系,我们再用一个平行的例子讲解这一套流程:我们希望输入 127.0.0.1:8000/students 能显示所有学生信息。
在 templates/myApp/students.html 中渲染界面:
<body>
<hl>学生信息列表hl>
<ul>
{%for student in students%}
<li>
{{student.sname}}--{{student.scontend}}
li>
{%endfor%}
ul>
body>
在 myApp/view.py 中定义视图:
from .models import Students
def students(request):
studentsList = Students.objects.all()
return render(request, 'myApp/students.html', {"students": studentsList})
在 myApp/urls.py 中配置 URL:
urlpatterns = [
re_path(r'^$', views.index),
re_path(r'^(\d+)/(\d+)/$', views.detail), # 正则匹配数字,()用来接收一个数字
re_path(r'^grades/$', views.grades),
re_path(r'^students/$', views.students),
]
成功显示:
有了班级列表和学生信息列表,我们想要点击班级列表中的班级,进而显示该班级下的所有学生的信息。首先将对应的 grades.html 中的 #
修改为 {{grade.id}}
,从而拿到班级的 id
:
<a href="{{grade.id}}">{{grade.gname}}a>
可以在 students.html 中添加下面的代码增加学生班级的显示,方便调试:
{{student.sname}}--{{student.scontend}}--{{student.sgrade}}
现在还要在视图中拿到点击的班级 id,我们定义视图为:
def gradesStudents(request, num):
# 获得对应的班级对象
grade = Grades.objects.get(pk=num)
# 获得班级下的所有学生对象列表
studentsList = grade.students_set.all()
return render(request, 'myApp/students.html', {"students": studentsList})
其中 Grades.objects.get(pk=num)
和 grade.students_set.all()
的讲解和使用见跑通 Django。
在班级列表点击班级后,URL 中会添加后缀 {{grade.id}}
,因此配置 URL 为:re_path(r'^grades/(\d+)$', views.gradesStudents)
。
得到结果:
至此,我们有关模板的基本操作就讲完啦,这一部分是 Django 的一个重点,因此还需要大家找一些小项目反复练习,后面的文章中也会继续更新项目的讲解