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. 广州Uber优步司机奖励政策(1月4日~1月10日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  2. P1113 杂务

    P1113 杂务 题目描述 John的农场在给奶牛挤奶前有很多杂务要完成,每一项杂务都需要一定的时间来完成它.比如:他们要将奶牛集合起来,将他们赶进牛棚,为奶牛清洗乳房以及一些其它工作.尽早将所有杂务 ...

  3. android stadio 编译报错:download fastutil-7.2.0.jar

    在Ubuntu上面,新安装的stadio,第一次编译项目的时候, 一直开在下载 fastutil-7.2.0.jar 原因是需要FQ.那么改一下你的buil.gradle buildscript { ...

  4. Windows Server 2008 R2 安装域

    在Windows Server 2008 R2里面安装域. 1.首先在"服务"里面添加"角色": 2.选择对应的域角色 3.安装完成后要启动配置向导 4.选择新 ...

  5. hugepages_settings.sh

    #!/bin/bash## hugepages_settings.sh## Linux bash script to compute values for the# recommended HugeP ...

  6. 网站端测试常见BUG

    1.翻页 翻页时,没有加载数据为空,第二页数据没有请求 翻页时,重复请求第一页的数据 翻页时,没有图片的内容有时候会引用有图片的内容 2.图片数据为空 图片数据为空时,会保留为空的图片数据位置 3.链 ...

  7. 分布式部署Apache-Jmeter粗略流程

    注意事项 Windows版和Mac版Jmeter可互相通信 确认被部署的机器安装有JDK并已配置好环境变量 Controller安装 1. 安装Jmeter,监视插件JMeterPlugins-Sta ...

  8. 用列主元消去法分别解方程组Ax=b,用MATLAB程序实现(最有效版)

    数值分析里面经常会涉及到用MATLAB程序实现用列主元消去法分别解方程组Ax=b 具体的方法和代码以如下方程(3x3矩阵)为例进行说明: 用列主元消去法分别解方程组Ax=b,用MATLAB程序实现: ...

  9. Django - day01 快速回忆ORM操作

    Django - day01 Model的增删改查找 得益于Django的ORM模型,用面向对象的思想来操作数据库使得数据库的操作一切变得简洁了很多. 0. 建表 在应用下的models.py中建立一 ...

  10. 【text】 文本组件说明

    text文本组件:在小程序里除了文本节点以外的其他节点都无法长按选中. 原型: <text selectable="[Boolean]" space="[ensp ...