完全可以从Django项目中直接从view.py Python文件中向网络浏览器发送HTML。在Django中处理HTML的一个更好的方法是使用Template。在Django中,模板只是一个存储在特定位置的HTML文件,它具有输出动态变量和内容的附加能力。与其在views.py文件中建立HTML,我们可以创建Django Template,其中有显示动态变量的占位符。为了在Django中使用模板,我们需要确保正确注册它们。
Django模板的位置
所以你已经准备好为你的Django项目创建一个新模板。你要把它放在哪里呢?Django的惯例是在你的app文件夹中开始,然后在该文件夹中创建一个名为templates的文件夹。然后在templates文件夹中,你要创建另一个与应用程序本身同名的文件夹。因此,如果我们正在开发一个目标应用程序,那么模板目录应该是goals/templates/goals。
创建一个模板
为了创建一个模板,我们可以在goals/templates/goals目录中添加一个HTML文件。让我们把这个文件命名为goal.html。
现在让我们在模板中添加一些基本的标记。在VS Code中,有一个名为Emmet的内置扩展,它可以帮助你减少输入,感谢快速建议。确保*"editor.quickSuggestions "的值:true*,如果你的VS Code emmet缩写不工作的话,请在settings.json中设置。
按Tab键,你的HTML模板现在应该有一些基础标记了。注意,我们还添加了带有一些文本的自定义H1标签。
C:\python\djangoprojects\myproject\goals\templates\goals\goal.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>The Template Works!</h1>
</body>
</html>
注册Django模板
如果我们试图通过视图函数来渲染这个模板,它还不能工作,我们会看到一个类似这样的错误。
TemplateDoesNotExist at /goals/daily
goals/goal.html
Request Method: GET
Request URL: http://127.0.0.1:8000/goals/daily
Django Version: 3.2.4
Exception Type: TemplateDoesNotExist
Exception Value:
goals/goal.html
为了使用我们的模板,我们必须在Django中注册它们。要在Django中注册模板,我们可以打开settings.py文件,找到与Templates相关的设置。这里显示的是开箱即用的设置。
C:\python\djangoprojects\myproject\myproject\settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
配置DIRS
上面的代码片段中的DIRS键是用来告诉Django在哪些目录路径下寻找HTML模板文件。这些路径应该是一个绝对路径,Django在settings.py文件中已经提供了一个BASE_DIR变量来帮助我们实现这一点。
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
使用这个变量,我们现在可以按照下面的方式配置DIRS,让Django知道我们的目标应用程序中的模板目录。
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
BASE_DIR / 'goals' / 'templates'
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
在HttpResponse中发送模板
模板的用例是,当一个特定的视图函数触发时,该模板的HTML被送回给用户。要做到这一点,模板需要被转换为一个HTML字符串,它可以与响应一起被送回给用户。要做到这一点,我们可以使用Django**render_to_string()**函数。我们可以像这样把它导入我们的views.py文件中。
from django.shortcuts import redirect, render
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from django.template.loader import render_to_string
现在我们可以在任何一个视图函数中使用**render_to_string()**函数,并把我们要渲染的模板的路径传给它。
def goals_by_timeframe(request, timeframe):
goal = goals[timeframe]
response_data = render_to_string('goals/goal.html')
return HttpResponse(response_data)
上面的代码将我们的模板渲染成一个HTML字符串,并将其存储在response_data变量中。在这一点上,我们用 response_data 变量返回一个 HttpResponse。现在,如果我们访问适当的URL来触发该视图函数,我们会看到模板正确地显示在网页浏览器中。
一个更好的注册模板的方法
我们能够让模板注册并在我们的Django项目中工作,但有一个更好的方法来做到这一点。显示的APP_DIRS键被设置为True。这意味着,Django默认会在应用目录内寻找模板文件。
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
那么,为什么Django在第一次尝试时没有找到我们创建的模板呢?原因是到目前为止,我们从未将我们的应用程序注册为settings.py中INSTALLED_APPS的一部分。只要你想让你创建的应用程序成为整个Django项目的一部分,你就必须在INSTALLED_APPS中注册它。这就完成了一个应用程序和包含的Django项目之间的几条线路,其中之一就是让Django知道该应用程序中的模板。因此,我们可以将TEMPLATES的设置保持在默认状态,并更新INSTALLED_APPS以包括我们新创建的目标应用程序。
INSTALLED_APPS = [
'goals',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
有了这个改变,我们的模板继续工作,我们所要做的就是把应用的名字添加到INSTALLED_APPS中,这样就可以向Django注册该应用的任何模板。对于特定应用的模板来说,这才是正确的做法。只需将APP_DIRS设置为True,并将应用名称添加到INSTALLED_APPS中。这是最好的做法,可以保持你的设置干净和可维护。