1. 使用模板(Template)
目前我们只是URL映射连接到view,但是Django框架是基于Model-View-Template结构,本节学习View-Template如何一起工作。
(在Django中,可以把模板看作构建一个完整HTML页面所需的脚手架。模板包含网页的静态部分(永远不会改变的部分),用特殊的语法(或模板标签)完成,可以被动态内容覆盖和替换,Django应用的视图可以替换这些动态内容来生成最终的HTML响应)
(1)为了让模板在Django App中运行起来,需要创建两个存放模板文件的目录:
• 在Workspace/tango_with_django_project/ 下创建一个新的文件夹叫 templates
• 在Workspace/tango_with_django_project/templates/ 下创建一个新的文件夹叫 rango
(2)告诉Django模板的存储位置
修改Workspace/tango_with_django_project/tango_with_django_project/settings.py文件。
默认情况下,当你创建一个新的Django项目时,文件中TEMPLATES结构看起来如下所示:
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列表来告诉Django模板的存储位置,DIRS列表默认设置为空列表。将字典键/值对更改为如下所示(需要使用绝对路径来定位模板目录):
'DIRS': ['<workspace>/tango_with_django_project/templates']
更好的解决方案:使用内置的Python函数自动计算出模板目录的路径。这样,无论你把Django项目的代码放在哪里,都可以获得一个绝对路径。这意味着项目变得更加可移植。
TEMPLATE_DIR = os.path.join(BASE_DIR, 'templates')
# 使用os.path.join()函数将BASE_DIR变量的值和字符串'templates'连接在一起
# 完成后,将生成<workspace>/tango_with_django_project/templates/
# 我们可以使用新的TEMPLATE_DIR变量来替换之前在TEMPLATES中定义的硬编码路径
# 更新TEMPLATE中DIRS键/值对,使其看起来像下面的代码片段:
'DIRS': [TEMPLATE_DIR, ]
(3)添加一个模板
现在模板目录&路径都设置好了,创建一个名为index.html的文件,并将其放在templates/rango/目录下
在这个新html文件中,添加以下HTML标记和Django模板代码
<!DOCTYPE html>
<html>
<head> <title>Rango</title> </head>
<body>
<h1>Rango says...</h1>
<div>
hey there partner! <br />
<strong>{{ boldmessage }}</strong><br />
<!--{{ boldmessage }}是Django template变量-->
</div>
<div>
<a href="/rango/about/">About</a><br />
</div>
</body>
</html>
(4)修改view
要使用这个模板,我们需要重新配置前面创建的index()视图。我们将改变视图来分派模板,而不是分派一个简单的响应。更新 view.py中的index():
def index(request):
# 构造一个字典,作为上下文传递给模板引擎
# context dictionary是一个将模板变量名boldmessage与Python变量映射在一起的Python字典
context_dict = {'boldmessage': 'Crunchy, creamy, cookie, candy, cupcake!'}
# Return a rendered response to send to the client.
# 返回一个render的响应发送给客户端,第一个参数是我们希望使用的模板
# render()接受用户的请求、模板文件名和context dictionary作为输入。
# render()函数将获取这些数据,并将其与模板结合在一起,以生成一个完整的HTML页面,该页面由一个HttpResponse返回。然后这个响应被返回并发送到用户的web浏览器。
return render(request, 'rango/index.html', context=context_dict)
(5)runserver 将看到下图:
2. 如何在Template中包含静态媒体文件
静态媒体文件:CSS (Cascading Style Sheets)、JavaScript以及图像。因为这些文件不是由web服务器动态生成的,它们只是简单地发送到客户的web浏览器。
(1)配置静态媒体目录
在项目目录Workspace/tango_with_django_project/下,创建static新目录
在static中创建images新目录
在images目录中放置一个图像
(2) 告诉Django新的static目录
在 Workspace/tango_with_django_project/tango_with_django_project/settings.py 添加一个指向静态目录的新变量&一个Django可以解析出新目录所在位置的数据结构
在settings.py的顶部创建一个名为STATIC_DIR的变量
STATIC_DIR = os.path.join(BASE_DIR, 'static')
# 这将创建路径Workspace/tango_with_django_project/static/
创建一个名为STATICFILES_DIRS的新数据结构–这本质上是 Django希望找到静态文件的路径列表(默认情况下,这个列表不存在,但在创建它之前请检查它是否存在)
STATICFILES_DIRS = [STATIC_DIR, ]
检查setting.py中是否定义了 STATIC_URL= ‘/static/’ (一般在文档的最下面定义)
(3)在html文件中添加静态文件
在workspace/templates/rango/index.html中添加图片:
<!DOCTYPE html>
<!--告诉Django的模板引擎将在模板中使用静态文件-->
{% load staticfiles %} <!-- New line -->
<html>
<head> <title>Rango</title> </head>
<body>
<h1>Rango says...</h1>
<div>
hey there partner! <br />
<strong>{{ boldmessage }}</strong><br />
</div>
<div>
<a href="/rango/about/">About</a><br />
<img src="{% static 'images/rango.jpg' %}" alt="Picture of Rango" /> <!-- New line -->
<!--模板标签{% %}表示,调用static把STATIC_URL中指定的URL和images/rango.jpg组合起来生成/static/images/rango.jpg-->
</div>
</body>
</html>
(4)runserver
【加载其他静态文件】
想在模板中引用静态文件时,使用{% static %}模板标签
下面的代码演示了HTML将JavaScript、CSS和图像包含到模板中
<!DOCTYPE html>
{% load staticfiles %}
<html>
<head>
<title>Rango</title>
<!-- CSS -->
<link rel="stylesheet" href="{% static "css/base.css" %}" />
<!-- JavaScript -->
<script src="{% static "js/jquery.js" %}"></script>
</head>
<body>
<!-- Image -->
<img src="{% static "images/rango.jpg" %}" alt="Picture of Rango" />
</body>
</html>
3. 怎样添加(动态)媒体文件
(1)在Workspace/tango_with_django_project/下新建media文件夹
(2)修改settings.py(与静态文件一样,媒体文件被上传到文件系统的指定目录中。我们需要告诉Django在哪里存储这些文件)
在Workspace/tango_with_django_project/tango_with_django_project/settings.py的顶部,在现有的BASE_DIR、TEMPLATE_DIR和STATIC_DIR变量下面,添加MEDIA_DIR
MEDIA_DIR = os.path.join(BASE_DIR, 'media')
# 这行代码告诉Django,媒体文件将被上传到你的Django项目的<workspace>/tango_with_django_project/media/
在settings.py空白处添加另外两个变量:
MEDIA_ROOT = MEDIA_DIR # 告诉Django在文件系统的这个位置查找已经上传和存储的媒体文件
MEDIA_URL = '/media/' # 告诉Django在文件系统从这个URL提供这些文件
(3)设置template context processor–方便地获得对MEDIA_URL路径的引用
在setting.py中找到TEMPLATES中的context_processors列表,添加一个要包含的新字符串:
'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.template.context_processors.media', # Check/add this line!
],
(4)调整URL
告诉Django从MEDIA_URL提供静态内容
打开项目的Workspace/tango_with_django_project/tango_with_django_project/urls.py
在顶部添加以下import语句(如果您发现其中一行已经存在,则不需要再次输入)
from django.conf import settings
from django.conf.urls.static import static
修改下面的urlpatterns列表 – 通过向刚才导入的static()函数追加一个调用来修改它,并通过设置告诉函数文件存储在文件系统的哪个位置(MEDIA_URL),以及应该从哪个URL提供它们(MEDIA_URL)
urlpatterns = [
...
...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# 可以从/media/ URL中提供项目的媒体目录中的内容
4. 总结Workflow
【创建模板并将其集成到Django视图中】
(1)首先创建希望使用的模板 并保存在Workspace/tango_with_django_project/tango_with_django_project/settings.py中指定的模板目录中
(2)在应用程序的views.py文件中查找或创建新视图。
(3)向视图添加特定的逻辑(如果有的话)。例如,这可能涉及从数据库中提取数据并将其存储在列表中。
(4)在这个视图中,构造一个dictionary对象,你可以将它作为模板上下文的一部分传递给模板引擎。
(5)使用render() 函数来生成呈现的响应–确保您引用了请求,然后是模板文件,最后是上下文字典。
(6)最后,通过修改项目的urls.py文件(或者特定于应用程序的urls.py文件,如果有的话)将视图映射到URL(这一步只在创建新视图或使用尚未映射的现有视图时才需要)
【将静态媒体文件放到页面上】
(1)获取希望使用的静态媒体文件,并将其放在项目的静态目录中。这个目录是在STATICFILES_DIRS中定义的——在settings.py中设置的变量之一
(2)在模板中添加对静态媒体文件的引用。e.g. 可以通过使用<img/>
标记将图像插入HTML页面
(3)在模板中使用{% load staticfiles %}
和{% static "<filename>" %}
命令来访问静态文件
【添加媒体文件】
(1)在项目的媒体目录中放置一个文件。媒体目录由项目的MEDIA_ROOT变量指定
(2)通过使用{{MEDIA_URL}}上下文变量链接到模板中的媒体文件。例如:
<img src="{{ MEDIA_URL }}cat.jpg" alt="Picture of a Cat."/>
5. 练习
(1)将about页面使用模板 => 使用一个名为about.html的模板。这个模板的内容基于index.html。在新模板的<h1>
元素中,保持‘Rango says…’-但是在下面一行,写上’here is the about page.’
(2)记住要更新views.py中的about()视图!您认为这个视图需要上下文字典吗?
(3)about.html必须包含一个链接回到index page
(4)about.html模板中,添加一个存储在项目静态文件中的图片。请用rango.jpg图像
(5)在about page中,包含一行‘This tutorial has been put together by your-name.’
=> 如果你从index.html复制过来,替换{{boldmessage}}将是最完美的地方
(6)在media的目录中添加一张cat.jpg
(7)在about.html模板中,添加一个<img>
标签来显示猫的图片,替代文本为’Picture of a Cat‘。在你的index page中保留Rango的静态图像,这样你的关于页面就有静态和媒体文件的工作示例。不需要修改about()视图,只需要修改about.html。
<!--Workspace/tango_with_rango_project/template/rango/about.html-->
<!DOCTYPE html>
{% load staticfiles %}
<html>
<head>
<title>Rango</title>
</head>
<body>
<h1>Rango says...</h1>
<div>
here is the about page. <br />
<strong>{{ boldmessage }}</strong><br />
</div>
<div>
<a href="/rango/">Index</a><br />
<img src="{% static 'images/rango.jpg' %}" alt="Picture of Rango" />
<img src="{{ MEDIA_URL }}cat.jpg" alt="Picture of a Cat."/>
</div>
</body>
</html>
# Workspace/tango_with_rango_project/rango/views.py #
def about(request):
#return HttpResponse("Rango says here is the about page. <a href='/rango/'>Index</a>")
context_dict = {'boldmessage': 'This tutorial has been put together by YifanZhou'}
return render(request, 'rango/about.html', context=context_dict)