2.1 自定义模板和静态文件位置
1 TEMPLATES = [ 2 { 3 'BACKEND': 'django.template.backends.django.DjangoTemplates', 4 'DIRS': [os.path.join(BASE_DIR,'templates'),], #① 5 'APP_DIRS': False, #② 6 'OPTIONS': { 7 'context_processors': [ 8 'django.template.context_processors.debug', 9 'django.template.context_processors.request', 10 'django.contrib.auth.context_processors.auth', 11 'django.contrib.messages.context_processors.messages', 12 ], 13 }, 14 }, 15 ]
语句①定义了模板文件的位置,并且该目录的名称templates也在这里定义了,BASE_DIR表示本项目的根目录,用os.path.join()函数将两者连接起来,即模板目录的位置是相对醒目根目录的templates目录----./templates。也可以按照自己的意愿来定义模板目录的名称和位置。
语句②将APP_DIRS设置为False,即不再允许Django按照默然方式寻找模板文件。
可以将所有应用的模板都放在./templates中。
2.1.2 自定义静态文件位置
在网站开发中,常常将网页中的CSS、JavaScript文件及网页上的图片称为静态文件----与被渲染的模板文件比较。
打开./testsite/setting.py文件,在最后几行中,会看到如下代码
1 # Static files (CSS, JavaScript, Images) 2 # https://docs.djangoproject.com/en/2.1/howto/static-files/ 3 4 STATIC_URL = '/static/'
上面两行注释的含义,第一行说明了Django中认定的静态文件是什么,第二行告诉我们想要知道怎么做可以去查看一个地址。最后一行代码的意思是如果通过URL访问静态文件,则可以通过(以刚刚建立的blog引用为例子)如http://localhost:8000/blog/static/newton.jpg的模式进行访问。要实现这个目的,需要在./blog目录中建立一个名为static的目录,然后将静态文件(如newton.jpg)放在里面。
编辑./testsite/settings.py文件,在STATIC_URL='/static'的下面增加如下代码。
1 STATIC_URL = '/static/' 2 STATICFILES_DIRS = ( 3 os.path.join(BASE_DIR,"static"), 4 )
重新启动Django服务,用浏览器再次打开http://127.0.0.1:8000/static/newton.jpg,能访问到静态文件

之所以能如此设置,是因为Django的settings配置变量中的STATICFILES_FINDERS的默认值规定了静态文件的查找顺序和内容。
1 STATICFILES_FINDERS = ( 2 "django.contrib.staticfiles.finders.FileSystemFinder", 3 "django.contrib.staticfiles.finders.AppDirectoriesFinder" 4 )
按照这个默认值,首先读取STATICFILES_DIRS中规定的静态文件(django.contrib.staticfiles.finders.FileSystemFinder),如果没有设置此值,就找不到什么,但不会对网站运行造成影响。然后通过django.contrib.staticfiles.finders.AppDirectoriesFinder在每个应用中查找有没有默认的静态文件目录static。如果在命名时将两处都做了设置,而且静态文件的名字还都一样,那么django会在找到第一个后终止查询。
2.1.3 通用静态文件和基础模板
所谓通用静态文件,就是会在很多应用中使用到的,比如jquery和bootstrap相关文件。
从下面网址分别下载jquery和bootstrap相关文件,然后放到已建立的static目录中。
https://v3.bootcss.com/和http://jquery.com/download/
目录结构如下所示:

这些通用的静态文件常常在基础模板中使用,比如第1章示例中的base.html。
一般来说,网站的界面可以大致分为上、中、下三个部分。上部就是头部,显示网站的LOGO和导航等;中部就是要显示的具体内容;下部就是底部,显示网站的版权信息或者诸如联系方式、购买流程等不怎么变化的信息或超链接。
按照上面的划分,头部和底部都可以做成基础模板。
在./templates目录中创建header.html文件和footer.html文件,header.html文件代码如下。
1 {% load staticfiles %} #① 2 <div class="container"> 3 <nav class="navbar navbar-default" role="navigation"> 4 <div class="navbar-header"> 5 <a class="navbar-brand" href="http://www.itdiffer.com"><img src="{%static '/images/logo.png'%}" 6 width="100px"></a> #② 7 </div> 8 <div> 9 <ul class="nav navbar-nav" role="navigation"> 10 <li><a href="{% url 'blog:blog_title' %">BLOG</a> </li> #③ 11 </ul> 12 <ul class="nav navbar-nav navbar-right"> 13 <li><a href="#">LOGIN</a> </li> 14 </ul> 15 </div> 16 </nav> 17 </div>
这就是所谓的头部代码。
语句①是模板中声明引入静态文件的标签,只有使用它,语句②中才能使用{% static 'images/logo.png' %},而不是用“硬编码”的方式写图片地址。语句②也是Django模板的一个语法,{% static %}可以用来引入某个静态文件,此处表示引入了静态文件中的一张图片,注意使用格式和文件路径。语句①写在语句②前面即可,此处之所以写在顶部,纯属习惯使然,没有特别规定。
语句③中的{% url 'blog:blog_title' %}使用了在./testsite/urls.py的URLconf中为应用设置的namespace和相关应用中的name值,拼接成该应用的入口链接URL。这样做同样是要避免“硬编码”。什么是硬编码?在开发中,如果在某个需要做超链接的地方使用了类似<a href="course/38">Django实战</a>的方式,就称之为“硬编码”,如果因为一些原因,URL目录结构发生了变化,则这种方式就会造成错误。
footer.html的代码如下:
1 <div class="container"> 2 <hr> 3 <p class="text-center">copy right www.itdiffer.com</p> 4 </div>
头尾代码编写完之后,把它们放到一个名为base.html的文件中进行整合,这个文件在前面已经创建好了,此处结合刚才编写的header.html和footer.html文件,将base.html文件重写。
1 <!DOCTYPE html> 2 {% load staticfiles %} 3 <html lang="zh-cn"> 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width,initial-scale=1"> 7 <title>{% block title %}{%endblock%}</title> 8 <link rel="stylesheet" href="{% static 'css/bootstrap.css %}"> 9 <hr/> 10 </head> 11 <body> 12 {% include "header.html" %} 13 <div class="container"> 14 {% block content %}{% endblock %} 15 </div> 16 {% include "footer.html" %} 17 {% block javascript %}{% endblock %} 18 </body> 19 </html>
2.1.4 重置管理后台模板
在浏览器打开http://127.0.0.1:8000/admin/,报错了

出现上述错误的原因,不难发现,我们已经将默认的文件模板位置都指向了自定义的模板位置,我们自定义的模板在网站目录的./templates中,到目前为止我们还没有将后台管理所对应的模板放到这里,在原来的Django配置中,并没有显明后台管理对应的模板位置,找到后台管理应用所对应的模板,然后放到./templates里面。Django所有后台管理模板都放在Django安装目录的./contrib/admin/templates/里面,对于目前的操作系统而言,就是在C:\Python35\Lib\site-packages\django\contrib\admin\templates中,其中有两个目录admin和registration,把它们都复制到我们这个项目的./templates里面。


复制完之后,重新启动Django服务器,再次浏览刚才的网址,就会打开管理页面,如下图所示:

2.1.5 知识点
1、模板
Django中的模板本质上也是一个独立的文本文件(其实不仅是Django,其他的Web框架模板也是如此),文件中包含了静态内容(比如HTML、CSS)和动态标记的数据。Django中的视图函数(后面会学习另外一种基于类的视图,在那种方式中就是类)决定了使用哪个模板及向模板渲染什么数据。编写模板所用的语言以HTML、CSS、JavaScript为主。
2、contexts
模板是一个动态文档,只有在显示动态信息时才能感受到它的存在。Django的视图函数在渲染模板(将有关数据传给模板)时使用的中介物就是contexts。contexts是一个包含了键值对的字典。如:return render(request,"blog/content.html",{"article":article,"publish":pub}),这条代码通过render()函数声明了所使用的模板("blog/content.html")和contexts{"article":article,"publish":pub})。在contexts的键值对中,“键”是即将在模板中使用的变量,这个变量可以引用任何在视图函数中确定的函数。
3、模板:for和if
所谓模板语法,就是根据Django的规定,在模板中使用通过contexts传入模板的数据对象。一般情况下有两类语法,一类是单独的变量,也称为变量标签;另一类是块命令,也称为块标签。
如,前面使用过的{{ publish }}就是变量标签,publish是contexts中的一个“键”,通过它将contexts键值对中的值传入模板,即在该位置显示所渲染的数据内容。注意,这种变量标签必须用{{ variable }}的形式-----使用双花括号(大括号)。
除变量标签外,还有“块标签”,下面代码实现for循环,就是一种块标签。
1 {% for blog in blogs %} 2 <li><a href="{{blog.id}}">{{ blog.title }}</a></li> 3 {% endfor %}
块标签以{% command% }开头({% for blog in blogs %}),并以{% endname %}结尾({% endfor %}),中间是块的内容,上例中的{{ bolg.title }}依然是变量标签,只不过这个变量的内容来自contexts的键blog引用的对象的一个属性(title).
对于for循环标签,在模板应用时,常常会使用循环计数功能,为此Django模板提供了默认的{{ forloop.counter }}从1开始计数的方式, 不需要视图函数中的contexts提供forloop键值对,只要是模板中的循环,都可以使用这样的方式实现对被循环内容的计数功能。另外,还有{{ forloop.counter0 }}是从零开始计数。
在模板中除可以实现for循环外,还可以实现if结构,其样式如下:
{% if condition %}
something
{% endif %}
注意:Django模板的if标签中也有类似Python的if ... else结构:
{% if condition %}
something
{% else %}
others
{% endif %}
以上两种状态块标签在模板中比较常用,而且它们也能够被嵌套使用。
浙公网安备 33010602011771号