Django学习系列之模板系统

Posted 差点点温柔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django学习系列之模板系统相关的知识,希望对你有一定的参考价值。

一、模板标签

if/else

{%  if  %}标签检查一个变量的值是否为真或者等于另外一个值,如果为真,系统会执行{%  if  %}和{%  endif  %}之间的代码块,例如:

{% if today_is_weekend %}
    <p>Welcome to the weekend!</p>
{% endif %}

{%  else  %}标签是可选的,如果不为真则执行{%  else  %}和{%  endif  %}之间的代码块

注意:一定要用{%  endif  %}关闭每一个{%  if  %}代码块

for

{%  for  %}允许我们在一个序列上迭代,与Python的 for 语句的情形类似,循环语法是for X in YY是要迭代的序列而X是在每一个特定的循环中使用的变量名称。每一次循环中,模板系统会渲染在{ % for % } 和{ % endfor % }之间的所有内容

示例一:for循环视图函数中传过来的列表

views.py

def home(request):
    TutorialList = ["html", "CSS", "jQuery", "Python", "Django"]
    return render(request, \'home.html\', {\'TutorialList\': TutorialList})

home.html

{% for i in TutorialList %}
{{ i }}
{% endfor %}

示例二:for循环视图函数传过来的列表中包含字典

views.py

ef user(request):
    user_list = []
    for i in range(5):
        temp = {\'user\':\'alex\'+str(i)}              #是这样的数据[{\'user\':alex1},{\'user\':alex2},{\'user\':alex3},{\'user\':alex4},{\'user\':alex5}]
        user_list.append(temp)
    return render(request,\'user.html\',{\'user_list\':user_list})

user.html

{% for item in user_list %}
       <li>{{ item.user }}</li>
{% endfor %}

示例三:for循环视图函数传过来的字典

views.py

def home(request):
    info_dict = {\'site\': \'自强学堂\', \'content\': \'各种IT技术教程\'}
    return render(request, \'home.html\', {\'info_dict\': info_dict})

home.html

站点:{{ info_dict.site }} 内容:{{ info_dict.content }}

在模板中取字典的键是用点info_dict.site,而不是Python中的 info_dict[\'site\'],效果如下

还可以这样遍历字典

{% for key, value in info_dict.items %}
    {{ key }}: {{ value }}
{% endfor %}

其实就是遍历这样一个 List:  [(\'content\', \'自强学堂\'), (\'site\', \'各种IT技术教程\')]

forloop

二、模板继承

概念:

模板继承是先构建一个基础模板框架,然后其他子模板继承这个基础模板

示例

定义urls.py

from django.conf.urls import url
from django.contrib import admin
from cmdb import views
urlpatterns = [
    url(r\'^assets/\', views.assets),
    url(r\'^user/\', views.user),
]

定义views.py

def assets(request):
    assets_list = []
    for i in range(10):
        temp = {\'host\':\'host\' + str(i)}
        assets_list.append(temp)
    return render(request,\'assets.html\',{\'assets_list\':assets_list})

def user(request):
    user_list = []
    for i in range(5):
        temp = {\'user\':\'alex\'+str(i)}
        user_list.append(temp)
    return render(request,\'user.html\',{\'user_list\':user_list})

定义基础模板(layout.py)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
     <style>
        .pg-header{
            height: 48px;
            background-color: cadetblue;
        }
        .pg-body{
            min-height: 500px;
        }
        .pg-body .body-menu{
            width: 20%;
            float: left;
        }
        .pg-body .body-content{
            width: 80%;
            float: left;
        }
        .pg-footer{
            height: 100px;
            background-color: brown;
        }
        .active{
            background-color: aquamarine;
            color: white;
        }
    </style>
</head>
<body>
    <div class="pg-header">
        后台系统V1
    </div>
    <div class="pg-body">
        <div class="body-menu">
            <ul>
                <li><a id="assets" href="/assets">资产管理</a></li>
                <li><a id="assets" href="/user"  >用户管理</a></li>
            </ul>
        </div>
        <div class="body-content">
             {% block body %}{% endblock %}      #这里表示子模板继承该模板之后,这里的值是可以被子模板中的值覆盖的
</div> </div> <div class="pg-footer"></div> </body> </html>

定义子模板(user.html)

{% extends \'layout.html\' %}              #引用layout.html模板

{% block body %}                         #这里表示覆盖掉基础模板中block body的部分
    <ul>
    {% for item in user_list %}
        <li>{{ item.user }}</li>
    {% endfor %}
    </ul>
{% endblock %}

定义子模板(assets.py)

{% extends \'layout.html\' %}                #引用layout.html模板

{% block body %}                           #这里表示覆盖掉基础模板中block body的部分 
    <ul>
    {% for item in assets_list %}
        <li>{{ item.host }}</li>
    {% endfor %}
    </ul>
{% endblock %}

效果展示

测试:在母板(基础模板)中把"后台系统V1"修改为"后台系统V2",然后两个子模板中随之改变

模板继承工作方式

在加载user.html和assets.html模板时,模板引擎发现{%  extends %}标签,注意到该模板是一个子模板,模板引擎立即加载其母模板,即本例中的layout.html

此时,模板引擎注意到一个{%  block  %}标签,并用子模板的内容替换掉block,模板引擎将会使用我们在{%  block body  %}中定义的内容

模板继承常见三层法

  1. 创建基础模板(母模板),主要在其中定义站点的外观,这些都是不常修改或者说是从不修改的内容
  2. 为网站的每个区域创建子模板,这些子模板对其基础模板(母模板)进行拓展,
  3. 为每种类型的页面创建独立的模板,例如论坛页面或者图片库,这些模板拓展相应的区域模板

这个方法可最大限度地重用代码,并使得向公共区域(如区域级的导航)添加内容成为一件轻松的工作

以下是模板继承的一些诀窍:

  • 如果在模板中使用{ % extends % } ,必须保证其为模板中的第一个模板标记,否则,模板继承将不起作用;
  • 一般来说,基础模板中的{ % block % }标签越多越好,记住,子模板不必定义父模板中所有的代码块,因此你可以用合理的缺省值对一些代码块进行填充,然后只对子模板所需的代码块进行(重)定义。 俗话说,钩子越多越好;
  • 如果发觉自己在多个模板之间拷贝代码,你应该考虑将该代码段放置到父模板的某个{ %block % }
  • 如果你需要访问父模板中的块的内容,使用这个标签吧,这一个魔法变量将会表现出父模板中的内容,如果只想在上级代码块基础上添加内容,而不是全部重载,该变量就显得非常有用了;
  • 不允许在同一个模板中定义多个同名的{ % block % } ,存在这样的限制是因为block标签的工作方式是双向的,也就是说,block标签不仅挖了一个要填的坑,也定义了在父模板中这个坑所填充的内容。如果模板中出现了两个相同名称的{ % block % }标签,父模板将无从得知要使用哪个块的内容;

  • { % extends % }对所传入模板名称使用的加载方法和get_template()相同。 也就是说,会将模板名称被添加到TEMPLATE_DIRS设置之后;

  • 多数情况下,{ % extends % }的参数应该是字符串,但是如果直到运行时方能确定父模板名,这个参数也可以是个变量,这使得你能够实现一些很酷的动态功能;

注意:假如index.html继承了base.html,  在index.html里能用的变量 在base.html也能用 

以上是关于Django学习系列之模板系统的主要内容,如果未能解决你的问题,请参考以下文章

3Python全栈之路系列之D

Django学习系列之基础

DJANGO入门系列之(模板层)

Django学习系列之路由系统

python学习点滴记录-Day17-django-part2

Django学习系列(三.模板template)