Django模板继承和静态文件

模板继承(extend)

Django模板引擎中最强大也是最复杂的部分就是模板继承了,模板继承可以让我们创建一个基本的"骨架"模板,它可以包含网页中的全部元素,并且可以定义能够被子模板覆盖的blocks。为了容易理解模板继承,我们先写一个模板:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}Replaceable template{% endblock %}</title>
</head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li><a href="/">Home</a> </li>
<li><a href="/blog">Blog</a> </li>
</ul>
{% endblock %}
</div> <div id="content">
{% block content %}{% endblock %}
</div>
</body>
</html>

这个模板,我们把它叫做base.html,它定义了一个可以用于两列排版页面的简单HTML骨架。"子模板"可以用它们的内容填充空白的blocks。在这个例子中,block标签定义了三个可以被子模板内容填充的block,block告诉模板引擎:子模板可能会覆盖掉模板中的这些位置。

接下来,我们再写一个子模板:

{% extends "polls/base.html" %}        # 模板路径根据项目或者app的路径来写,笔者这里的模板位于app中

{% block title %}Child template{% endblock %}

{% block content %}
{% for entry in blog_entries %}
<h3>{{ entry.title }}</h3>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}

extends标签是这里的关键,它告诉模板引擎这个模板继承了另一个模板。当模板系统处理这个模板时,首先定位父模板--此例中,就是"base.html"。那时模板引擎注意到base.html中的三个block标签,并用子模板中的内容来替换这些block。根据blog_entries的值,子模板输出的内容会是下面的内容:

<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>Child template</title>
</head> <body>
<div id="sidebar">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
</div> <div id="content">
<h2>Entry one</h2>
<p>This is my first entry.</p> <h2>Entry two</h2>
<p>This is my second entry.</p>
</div>
</body>
</html>

注意:子模板并没有定义sidebar block,所以系统使用了父模板中的值。父模板的{% block %}标签中的内容总是被用作备选内容。这种方式使代码得到最大程度的复用,并且使得添加内容到共享的内容区域更加简单,例如:部分范围内的导航。

说明:

1.如果在模板中使用{% extends %}标签,它必须是模板中的第一个标签,其他的任何情况下,模板继承都将无法工作;

2.在base模版中设置越多的 {% block %} 标签越好。请记住,子模版不必定义全部父模版中的block,所以,我们可以在大多数>block中填充合理的默认内容,然后,只定义我们需要的那一个。多一点钩子总比少一点好;

3.如果发现我们在大量的模板中复制内容,那就意味着我们应该把内容移动到父模板中的一个{% block %}中;

4.有时候,想在父模板的基础上再添加点其他的,而不是完全覆盖父模板的内容,那么我们只需要在想要填充的块里,再加上 >{{ block.super }}语句,我们就可以把父模板里的东西给留下来,如:

父模板中的
{% block title %}Parent template{% endblock %} 如果我们只想子模板的结果是在后面添加一个!,则只需要在子模板中写成
{% block title %}
{{ block.super }}!
{% endblock %}

5.为了更好的可读性,也可以给我们的 {% endblock %} 标签一个 名字 。例如:

{% block content %}
...
{% endblock content %} 

6.在大型模板中,这个方法可以帮助我们清楚的看到哪个 {% block %}标签被关闭了;

最后,请注意我们不能在一个模版中定义多个相同名字的 block 标签。这个限制的存在是因为block标签的作用是“双向”的。这个意思是,block标签不仅提供了一个坑去填,它还在父模版中定义了填坑的内容。如果在一个模版中有两个名字一样的 block 标签,子模版的父模版将不知道使用哪个block的内容。

注意:模板一般放在app下的templates中,Django会自动去这个文件夹中找。但 假如我们每个app的templates中都有一个 index.html,当我们在views.py中使用的时候,直接写一个 render(request, 'index.html'),Django 能不能找到当前 app 的 templates 文件夹中的 index.html 文件夹呢?(答案是不一定能,有可能找错)

Django模板查找机制:Django 查找模板的过程是在每个 app 的 templates 文件夹中找(而不只是当前 app 中的代码,只在当前 app 的 templates 文件夹中找)。各个 app 的 templates 形成一个文件夹列表,Django 遍历这个列表,一个个文件夹进行查找,当在某一个文件夹找到的时候就停止,所有的都遍历完了还找不到指定的模板的时候就是 Template Not Found (过程类似于Python找包)。这样设计有利当然也有弊,有利是的地方是一个app可以用另一个app的模板文件,弊是有可能会找错了。所以我们使用的时候在 templates 中建立一个 app 同名的文件夹,这样就好了。这就需要把每个app中的 templates 文件夹中再建一个 app 的名称,仅和该app相关的模板放在 app/templates/app/ 目录下面。这样在使用的时候,有app作为名称的一部分,就不会混淆。

模板include

假如我们有以下模板index.html,代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <div>网页公共头部部分</div> <h2> 网页body部分 </h2> <div>网页公共底部部分</div> </body>
</html>

做过web开发的同学都知道大部分网页的公共头部,公共底部部分代码每个页面都一样,那么就应该将其单独拿出做为一个html, 这样修改这部分代码时候,不需要每个页面都修改, 所以在django中我们可以这么做:

top.html

<div>网页公共头部部分</div>

bottom.html

<div>网页公共底部部分</div>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> {% include 'top.html' %} <h2> 网页body部分 </h2> {% include 'bottom.html' %} </body>
</html>

我们可以使用Django模板引擎的include语法,来将单独的页面包含到当前模板页面中。有同学有疑问,那我们通过视图传递给模板的上下文,在被包含的模板中可以使用吗?可以直接使用,假如我们的视图函数如下:

def index(request):
return render(request, 'polls/index.html', {'a': 100, 'b': 200})

该Django视图函数,传递给模板并渲染模板。

top.html修改如下:

<div>网页公共头部部分:{{ a }}</div>      # 这样使用没有任何问题

我这里有这样的一个问题,假如所有的页面都使用共同的头部top.html, 可能针对1.html 2.html 3.html所使用的头部有些样式不一样,所需top.html:

<div classs='acss'>网页公共头部部分</div>

但是对于5.html, 6.html使用的头部样式为:

<div class='bcss'>网页公共头部部分</div>

很显然,如果直接通过include方式包含公共头部,会导致一些页面显示问题。既然部分参数不一样,include允许我们传递参数给被include的模板,我们可以使用with语法,那么问题解决如下:

{{ % include 'top.html' with mycss='acss' % }}

top.html修改如下:

<div class='{{mycss}}'>网页公共头部部分</div>

被包含模板中部分参数,由我们include的时候动态指定,那么top.html就不会因为细微差别而编写多份代码了。

静态文件配置

我们自己导入的一些页面相关的包就叫做静态文件

  • 在app目录中先创建static目录;
  • 在static目录里面导入我们的JS、CSS、Jquery和Bootstrap等;
  • 在项目settings.py中添加一些配置;
STATIC_URL = '/static/'   #这个配置就相当于下面配置的别名,如果这里的名字修改了就按照这里的名字去导入
STATICFILES_DIRS = [
os.path.join(BASE_DIR,"static") #E:\day68\static 找到static路径
]
  • 导入网页相关图片、CSS、JS、Jquery等
<link rel = "stysheet",href= "/static/index.css/"> 

<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">

Django 2.0 学习(13):Django模板继承和静态文件的更多相关文章

  1. Django(五)框架之模板继承和静态文件配置

    https://www.cnblogs.com/haiyan123/p/7731959.html 一.模板继承 目的是:减少代码的冗余 语法: {% block classinfo %} {% end ...

  2. Django框架(八)—— 模板层:模板导入、模板继承、静态文件

    目录 模板导入.继承.静态文件 一.模板导入 1.语法 2.使用 二.模板的继承 1.使用模板的继承 2.强调(注意点) 三.静态文件 1.在配置文件settings中配置过静态文件 2.导入使用静态 ...

  3. Django框架之模板继承和静态文件配置

    一.模板继承 目的是:减少代码的冗余 语法: {% block classinfo %} {% endblock %} 具体步骤: 1.创建一个base.html文件,2.把要显示的页面的内容写在这里 ...

  4. Django框架----模板继承和静态文件配置

    母板 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8& ...

  5. Django框架(七)-- 模板层:模板导入、模板继承、静态文件

    一.模板导入 要复用一个组件,可以将该组件写在一个文件中,在使用的时候导入即可 在模板中使用 1.语法 {% include '模板名字' %} 2.使用 ad.html页面 <div clas ...

  6. Django 2.0 学习(07):Django 视图(进阶-续)

    接Django 2.0 学习(06):Django 视图(进阶),我们将聚焦在使用简单的表单进行处理和精简代码. 编写简单表单 我们将用下面的代码,来替换之前的detail模板("polls ...

  7. Django 2.0 学习(09):Django 静态文件(样式和背景图片)

    应用的定制化:静态文件 首先,在polls目录中创建一个名叫static的目录.Django会在该目录里面查找静态文件,类似于Django在polls/template目录下查找模板文件. Djang ...

  8. Django框架(二)—— 基本配置:app注册、模板配置、静态文件配置、数据库连接配置post和get

    目录 app注册.模板配置.静态文件配置.数据库连接配置post和get 一.app 二.模板配置 三.静态文件配置 四.数据库连接配置 五.get请求和post请求 六.新手三件套 七.登录功能案例 ...

  9. Django模板变量及静态文件引用

    一.模板变量传递 1.视图向模板传递变量 视图中的列表,数组,字典,函数均可以传递给模板 在视图中定义变量通过render(content{‘name’ : value})传递给模板 模板通过{{  ...

随机推荐

  1. 初试Docker on Debian on VirtualBox

    一直以来都对Docker如雷贯耳,很想尝试一下但都被各种忙给耽误了,最近由于项目调试,需要安装 Oracle 和 SQL Server 数据库,但又不想安装到本机系统里,于是下决心啃一下docker这 ...

  2. 仿京东淘宝商品详情页属性选择js效果

    在网上找了好久发现都不符合要求就自己摸索写了一个,用到了linq.js这个linq to js 扩展,不然用纯JS遍历json查询要死人啊 demo:http://123.207.28.46:8086 ...

  3. Windows运行机理——消息与消息队列

    Windows运行机理这系列文章都是来至于<零基础学Qt4编程>——吴迪,个人觉得写得很好,所以进行了搬运和个人加工 Windows程序设计时一种基于消息的时机驱动方式的设计模式,完全不同 ...

  4. Siki_Unity_1-6_C#编程初级教程(未学)

    Unity 1-6 C#编程初级教程 任务1:C#和.Net框架 C#是.Net里的一个成分 2002年微软发布第一个.Net框架(多平台,行业标准,安全性) .Net框架 IDE编程工具 --产生- ...

  5. TW实习日记:第23天

    主要的项目已经在修改一些细节以提高用户体验的阶段了,所以并不是太忙,主要就是对样式和一些细节修修改改.然后下午帮助同事的新项目做了一个功能点,主要就是调通接口就行,因为参数巨多,所以总要和网端那边的后 ...

  6. 82. Single Number [easy]

    Description Given 2*n + 1 numbers, every numbers occurs twice except one, find it. Example Given [1, ...

  7. [Clr via C#读书笔记]Cp10属性

    Cp10属性 属性的本质就是方法,只是看起来像字段罢了: 无参属性 就是一般属性: 字段一般要private,然后通过设置访问方法-访问器来访问:属性是方法语法变种:getset不一定要访问支持字段: ...

  8. python 打包

    一.下载 pip install Pyinstaller 二.使用Pyinstaller 1.使用下载安装的方式安装的Pyinstaller打包方式 将需要打包的文件放在解压得到的Pyinstalle ...

  9. C++ 学习笔记之——STL 库 vector

    vector 是一种顺序容器,可以看作是可以改变大小的数组. 就像数组一样,vector 占用连续的内存地址来存储元素,因此可以像数组一样用偏移量来随机访问,但是它的大小可以动态改变,容器会自动处理内 ...

  10. matlab 常用集合相关的函数

    Matlab常用的集合相关的函数如下:     union(A,B)              %求集合A和集合B的并集     intersect(A,B)             %求集合A和集合 ...