Python

3.8 Django 模板之 Template(1)

2018-04-27  本文已影响38人  昵称又重复

生命就应该不自量力地还手,直至死方休

目录来了

  1. 模板介绍
    1.1 模板处理
    1.2 快捷函数
  2. 模板语言DTL
    2.1 变量
    2.2 在模板中调用对象的方法
    2.3 标签(9个标签)
    2.4 过滤器
    2.5 示例
      2.5.1 模板
      2.5.2 视图函数
  3. 模板继承
    3.1 说明
    3.2 三层继承结构

—————————————————————————

1. 模板介绍

作为 Web 框架, Django 提供了模板,可以很便利的动态生成 HTML
 模版系统致力于表达外观,而不是程序逻辑
 模板的设计实现了业务逻辑(view)与显示内容(template)的分离,一个视图可以使用一个模板也可以供多个视图使用
 模板包含
 HTML 的静态部分
 动态插入内容部分
 Django 模板语言,简写 DTL,定义在 django.template 包中
 由 startproject 命令生成的 settings.py 定义关于模板的值:
 DIRS 定义了一个目录列表,模板引擎按列表顺序搜索这些目录以查找模板源文件
 APP_DIRS 告诉模板引擎是否应该在每个已安装的应用中查找模板
 常用方式:在项目的根目录下创建 templates 目录,设置 DIRS 值

DIRS=[os.path.join(BASE_DIR,"templates")]

—————————————————————————

1.1 模板处理

Django 处理模板分为两个阶段
Step1 加载:根据给定的标识找到模板后预处理,将它编译好放在内存中返回一个 Template 对象

loader.get_template(template_name),

 Step2 渲染:使用 Context 数据对模板插值并返回生成的字符串
Template 对象的 render(RequestContext)方法,使用 context 渲染模板
 加载渲染完整代码:

from django.template import loader, RequestContext
from django.http import HttpResponse
def index(request):
    tem = loader.get_template('temtest/index.html')
    context = {}
return HttpResponse(tem.render(context))

—————————————————————————

1.2 快捷函数

为了减少加载模板、渲染模板的重复代码, django 提供了快捷函数
 render_to_string("")
 render(request,'模板',context)

from django.shortcuts import render
def index(request):
return render(request, 'temtest/index.html')

—————————————————————————

2.模板语言DTL

模板语言包括
 变量
 标签 { % 代码块 % }
 过滤器
 注释{# 代码或 html #}

—————————————————————————

2.1 变量

语法:

{{ variable }}

 当模版引擎遇到一个变量,将计算这个变量,然后将结果输出
 变量名必须由字母、数字、下划线(不能以下划线开头)和点组成
 当模版引擎遇到点("."),会按照下列顺序查询:
 字典查询,例如: foo["bar"]
 属性或方法查询,例如: foo.bar
 数字索引查询,例如: foo[bar]
如果变量不存在, 模版系统将插入'' (空字符串)

—————————————————————————

2.2 在模板中调用对象的方法

在模板中调用方法时不能传递参数
 在 models.py 中定义类 HeroInfo

from django.db import models
class HeroInfo(models.Model):
    ...
    def showName(self):
return self.hname

 在 views.py 中传递 HeroInfo 对象

from django.shortcuts import render
from models import *
def callMethodInTemplate(request):
    hero = HeroInfo(hname='abc')
    context = {'hero': hero}
return render(request, 'booktest/detail2.html', context)

 应用 urlcof 中添加:

url(r'^callMethodInTemplate/$', views.callMethodInTemplate),

在模板 detail2.html 中调用

{{hero.showName}}

—————————————————————————

2.3 标签(9个标签)

语法:
{ % tag % }
for 标签
循环逻辑: {%for ... in ...%}
注意:
1、 %和{}中间没有空格 { % % }写法是不对的
2、 Django 不支持退出循环操作。 如果想退出,可以让迭代变量仅包含需要迭代的项目。
3、 Django 也不支持 continue 语句,我们无法让当前迭代操作跳回到循环头部。

语法:

{{forloop.counter}}

表示当前是第几次循环

{%empty%}

给出的列表空为或列表不存在时,执行此处

{%endfor%}

范例

{%for item in heroList%}
<div>{{ forloop.counter }}: {{ item.showName }}</div>
<div>当前是第{{forloop.counter}}次循环</div>
    {%empty%}
<div>给出的列表为或列表不存在时,执行此处</div>
    {%endfor%}
    reversed 标签: 使得该列表被反向迭代
{%for item in heroList reversed %}

if 标签

{%if ...%}

逻辑 1

{%elif ...%}

逻辑 2

{%else%}

逻辑 3

{%endif%}

范例

{%if hero.showName == '黄蓉'%}
<div>黄蓉</div>
{%else%}
<div>其他英雄</div>
{%endif%}

注意:
hero.showName == 之间一定要有空格!
如果连在一起写 hero.showName==, 程序会将它们看成了一个整体而报错:
Could not parse the remainder: '=='1'' from 'sort=='1''
逻辑运算符
and 表示两个条件同时满足
or 表示只满足一个条件即可(or 和 and 不可以同时使用)
not 也是合法的
注释标签
多行注释

{% comment %}

多行注释

{% endcomment %}

范例

{% comment %}
This is a
multi-line comment.
{% endcomment %}
单行注释
{# 这是一个注释 #}
范例
This is a {# this is nota comment #}test.

include 标签
 加载模板并以标签内的参数渲染

{%include "foo/bar.html" %}

反向生成 url

{ % url 'name' p1 p2 %}

范例

<a href="{% url 'booktest.views.detail' book.id %}">{{ book.btitle }}</a>
csrf_token

 这个标签用于跨站请求伪造保护

{ % csrf_token %}

布尔标签
 and、 or, and 比 or 的优先级高
其它标签
 block、 extends:详见“模板继承”
 autoescape:详见“HTML 转义”

—————————————————————————

2.4 过滤器

语法

{ { 变量|过滤器 }}

 例如{ { name|lower }},表示将变量 name 的值变为小写输出
管道符号|
 应用于过滤器, 通过使用过滤器来改变变量的计算结果
范例
在 if 标签中使用过滤器结合运算符
if list1|length > 1
 过滤器链
 过滤器能够被“串联” ,构成过滤器链

name|lower|upper

 过滤器参数传递
 参数使用引号包起来
list|join:", "
 设置默认值
 default:如果一个变量没有被提供,或者值为 false 或空,则使用默认值,否则使用变量的值value|default:"什么也没有"
 date
 根据给定格式对一个 date 变量格式化

value|date:'Y-m-d'slicevalue |slice:'10'

 详细的过滤器
https://docs.djangoproject.com/en/2.0/ref/templates/builtins/

—————————————————————————

2.5 示例

示例
 查询所有英雄信息显示出来,要求奇数行显示为红色,偶数行显示为蓝色

—————————————————————————

2.5.1 模板

模版

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
   .red {
       color: red;
       background-color: white;
     }
    .blue {
        color: blue;
        background-color: gray;
    }
</style>
</head>
<body>
  {% for item in ls %}
  {% if item.color == 'red' %}
  <div class="red">{{ item.hero.hname }}</div>
    {%else%}
  <div class="blue">{{ item.hero.hname }}</div>
    {%endif%}
    {% endfor %}
</body>
</html>

—————————————————————————

2.5.2 视图函数

def getlist(request):
  ls = HeroInfo.objects.all()
  count = ls.count()
  ls1 = []
  for i in range(count):
    tmp = {}
    tmp['hero'] = ls[i]
    if i % 2 == 0:
        tmp['color'] = 'blue'
    else:
        tmp['color'] = 'red'
        ls1.append(tmp)
        context = {'ls':ls1}
return render(request,'colortest.html',context)

—————————————————————————

3.模板继承

模板继承可以减少页面内容的重复定义,实现页面内容的重用
 典型应用:网站的头部、尾部是一样的,这些内容可以定义在父模板中,子模板不需要重复定义
 block 标签:在父模板中预留区域,在子模板中填充
 extends 继承:继承,写在模板文件的第一行定义父模板 base.html

{ %block block_name%}

这里可以定义默认值
如果不定义默认值,则表示空字符串

{ %endblock%}

 定义子模板 index.html

{ % extends "base.html" %}

 在子模板中使用 block 填充预留区域

{ %block block_name%}

实际填充内容

{ %endblock%}

—————————————————————————

3.1 说明

如果发现在模板中大量的复制内容,那就应该把内容移动到父模板中
 如果在模版中使用 extends 标签,它必须是模版中的第一个标签
 不能在一个模版中定义多个相同名字的 block 标签
 子模版不必定义全部父模版中的 blocks,如果子模版没有定义 block,则使用了父模版中的默认值, 使用可以获取父模板中 block 的内容
 为了更好的可读性,可以给 endblock 标签一个名字

{ % block block_name %}

区域内容

{ % endblock block_name %}

—————————————————————————

3.2 三层继承结构

三层继承结构使代码得到最大程度的复用,并且使得添加内容更加简单
 如下图为常见的电商页面

1.创建根级模板
 名称为“base.html”
 存放整个站点共用的内容

<!DOCTYPE html>
<html>
<head>
    <title>{%block title%}{%endblock%} 水果超市</title>
</head>
<body>
    top--{{logo}}
    <hr/>
    {%block left%}{%endblock%}
    {%block content%}{%endblock%}
<hr/>
bottom
</body>
</html>

2.创建分支模版
 继承自 base.html
 名为“base_*.html”
 定义特定分支共用的内容
 定义 base_goods.html

{%extends 'temtest/base.html'%}
{%block title%}商品{%endblock%}
{%block left%}
<h1>goods left</h1>
{%endblock%}

定义 base_user.html

{%extends 'temtest/base.html'%}
{%block title%}用户中心{%endblock%}
{%block left%}
<font color='blue'>user left</font>
{%endblock%}

 定义 index.html,继承自 base.html,不需要写 left 块

{%extends 'temtest/base.html'%}
{%block content%}
首页内容
{%endblock content%}

3.为具体页面创建模板,继承自分支模板
 定义商品列表页 goodslist.html

{%extends 'temtest/base_goods.html'%}
{%block content%}

商品正文列表

{%endblock content%}

 定义用户密码页 userpwd.html

{%extends 'temtest/base_user.html'%}
{%block content%}

用户密码修改

{%endblock content%}

4.视图调用具体页面,并传递模板中需要的数据
 首页视图 index

logo='welcome to MyMoon YouHeart'
def index(request):
return render(request, 'temtest/index.html', {'logo': logo})

 商品列表视图 goodslist

def goodslist(request):
return render(request, 'temtest/goodslist.html', {'logo': logo})

 用户密码视图 userpwd

def userpwd(request):
return render(request, 'temtest/userpwd.html', {'logo': logo})

5.配置 url

from django.conf.urls import url
from . import views
urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^list/$', views.goodslist, name='list'),
    url(r'^pwd/$', views.userpwd, name='pwd'),
]

感谢语

一口气连着写了好几篇文章,哎!没有期待就没有未来!一首有没有人曾告诉你在我耳朵里逍遥了一上午了!我听见有人欢呼,有人在哭泣!!!

上一篇下一篇

猜你喜欢

热点阅读