码迷,mamicode.com
首页 > 其他好文 > 详细

63、django之模版层(template)

时间:2017-10-24 21:02:46      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:原因   部门   翻译   hello   开会   ons   tin   text   rom   

上篇主要介绍了django的MTV模型,主要介绍了视图层之路由配置系统url分发和视图层之视图函数view,本篇主要讲解MTV模型中的模版层template。

 

模版层(template)

 

一、模版简介

1、在我们之前写的代码还有没有记得最后返回是一个网页(上篇随笔)

示例:

def index(request):
    name="yuan"
    return render(request,"index.html",{"n":name})

每次我们创建一个新项目的时候路径下都会自带一个templates,没错这个文件夹就是用来放我们的html代码的。

所以说我们通俗的讲模版就是html代码+模版语法

模版包括在使用时会被值替换掉的 变量,和控制模版逻辑的 标签。

2、还有你可能已经注意到我们有一个例子视图中返回文本的方式有点特别。(上篇随笔)

也就是说,HTML被直接硬编码在 Python代码之中:

from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

尽管这种技术便于解释视图是如何工作的,但直接将HTML硬编码到你的视图里却并不是一个好处理方式。

3、HTML被直接硬编码在 Python代码中的缺点

1)对页面设计进行的任何改变都必须对 Python 代码进行相应的修改。 站点设计的修改往往比底层 Python 代码的修改要频繁得多,因此如果可以在不进行 Python 代码修改的情况下变更设计,那将会方便得多。

2)Python 代码编写和 HTML 设计是两项不同的工作,大多数专业的网站开发环境都将他们分配给不同的人员(甚至不同部门)来完成。 设计者和HTML/CSS的编码人员不应该被要求去编辑Python的代码来完成他们的工作。

3)程序员编写 Python代码和设计人员制作模板两项工作同时进行的效率是最高的,远胜于让一个人等待另一个人完成对某个既包含 Python又包含 HTML 的文件的编辑工作。

基于这些原因,将页面的设计和Python的代码分离开会更干净简洁更容易维护。 我们可以使用 Django的 模板系统 (Template System)来实现这种模式,这就是本章要具体讨论的问题。

4、我们来看看上面这段代码的其他实现方式

1)django模板修改的视图函数

from django.shortcuts import render,HttpResponse

def timeHandle(request):
    import datetime
    t=datetime.datetime.now()

    from django.template import Template, Context
    templateObj=Template("<h1 style=‘color:red‘>current time: {{ time }}</h1>")
    contextObj=Context({"time":str(t)})
    html=templateObj.render(contextObj)
    
    return HttpResponse(html)

2)优化后的写法(推荐)

from django.shortcuts import render,HttpResponse

def timeHandle(request):
    import datetime
    t=datetime.datetime.now()
    return render(request,"time.html",{"time":str(t)[:19]})

template--->time.html:

<body>
<h1>current time: {{ time }}</h1>
</body>

 

二、模版之变量

1、语法:

{{ var }}

2、深度查询: 通过句点符号 .

3、示例:

1)view:

def index(request):
    name="hello template"
    i=200
    l=[111,[333,444,555],333]
    d={"name":"yuan","age":23}
    class Person(object):
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def dream(self):
            return "I am dreaming"
    person_bjd=Person("bjd",20)

    #return render(request,"index.html",{"name":name,"i":i,"l":l,"d":d,"person_egon":person_bjd})
    return render(request,"index.html",locals())

locals()可以代替传参,但是必须在html里的模版变量和view里的变量名一致,耗资源,不推荐。

2)template

<p>{{ name }}</p>
<p>{{ i }}</p>
<p>{{ l.1 }}</p>
<p>{{ d.name }}</p>
<p>{{ person_egon.name }}</p>
<p>{{ person_egon.age }}</p>
<p>{{ person_egon.dream }}</p>

注意:句点符只可以用来引用对象的无参数方法


 

三、模版之过滤器

1、语法:

{{obj|filter_name:param}}

2、default 设置默认

如果一个变量是false或者为空,使用给定的默认值。例如:

{{ value|default:"查询为空" }}

3、lenght 长度

返回值的长度。它对字符串和列表都起作用。例如:

{{ value|length }}

4、filesizeformat 文件大小

将值格式化为一个 “人类可读的” 文件尺寸 (例如 ‘13 KB‘‘4.1 MB‘‘102 bytes‘, 等等)。例如:

{{ value|filesizeformat }}

如果 value 是 123456789,输出将会是 117.7 MB

4、date 时间

{{ t|date:"Y-m-d" }}

5、slice 切分

可以将我们需要的部分切分出来

{{ value|slice:"2:-1" }} 

顾头不顾尾

6、truncatechars与truncatewords 截断

按照指定的字符或单词数量截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。

参数:要截断的字符数或单词数

{{ value|truncatechars:20 }}    <!--按字符截断-->
{{ value|truncatewords:5 }}    <!--按单词截断-->

7、safe 安全机制

Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。

但是有的时候我们可能不希望这些HTML元素被转义,我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如:

value="<a href="">点击</a>"
{{ value|safe}}

8、更多过滤器

http://python.usyiyi.cn/translate/django_182/ref/templates/builtins.html#ref-templates-builtins-tags


 

四、模版之标签

1、语法

{% tag %}

2、for 标签  遍历

{% for person in person_list %}
    <p>{{ person.name }}</p>
{% endfor %}    <!--必须有的结束符-->

{% for k,v in d.items %}
     <p>{{ k }},{{ v }}</p>
{% endfor %}


{% for person in personList reversed %}
     <p>{{ forloop.counter }}---{{ person.name }},{{ person.age }}</p>
{% endfor %}

可以利用{% for obj in list reversed %}反向完成循环。

循环序号可以通过{{forloop}}显示::

forloop.counter    从1开始计数
forloop.counter0    从0开始基数
forloop.revcounter    倒序到1结束
forloop.revcounter0    倒序到0结束
forloop.first    是一个布尔值,如果该迭代是第一次执行,那么它被置为True
forloop.last    是一个布尔值,如果该迭代是最后一次执行,那么它被置为True

for 标签带有一个可选的{% empty %} 从句,在给出的组是空的或者没有被找到时执行

{% for person in person_list %}
    <p>{{ person.name }}</p>

{% empty %}
    <p>sorry,no person here</p>
{% endfor %}

3、if 标签 分支

{% if num > 100 or num < 0 %}
    <p>无效</p>
{% elif num > 80 and num < 100 %}
    <p>优秀</p>
{% else %}
    <p>凑活吧</p>
{% endif %}

除了格式和其他编程语言用法相同不做过多阐述。

4、with 缓存

使用一个简单地名字缓存一个复杂的变量,当你需要使用一个复杂的变量很多次的时候是非常有用的

{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

5、csrf_token

上篇随笔我们在最后写了一个注意,那是不正确的方法,我们所注释掉的一行是保护机制,这样想当时失去了保护,之所以介绍此方法是应为还没有接触到模版标签,csrf_token就是用来解决post请求的。(用于跨站请求伪造保护)

<form action="/login/" method="post">
    {% csrf_token %}
    <p><input type="text" name="user"></p>
    <input type="submit">
</form>

看看这个标签在浏览器中检查的结果

技术分享

它是隐藏的,value值相当于带着一个服务器给它的身份证,没有身份证的post请求会被拒绝,value值是打开登录页面是get请求的时候返回的。


 

六、自定义标签和过滤器

自定义标签和过滤器过程:

1、在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.

 一般默认已经配置好了如果没有配置自己加上

INSTALLED_APPS = [
    ‘django.contrib.admin‘,
    ‘django.contrib.auth‘,
    ‘django.contrib.contenttypes‘,
    ‘django.contrib.sessions‘,
    ‘django.contrib.messages‘,
    ‘django.contrib.staticfiles‘,
    ‘app1.apps.App1Config‘,    #默认已有 如果没有只要添加app名称即可 例如: ‘app1‘
]

2、在app中创建templatetags模块(模块名只能是templatetags)

模块名是固定的不能自己起名,因为django会自己在此模块找

3、创建任意 .py 文件,如:my_tags.py

此文件名为自定义

from django import template
from django.utils.safestring import mark_safe

register = template.Library()   #register的名字是固定的,不可改变

@register.filter
def multi(x,y):
    return x*y

@register.simple_tag
def multiTag(x,y,z):
    return x*y*z

前三行也是固定的不可改变

如果是自定义过滤器加@register.filter装饰器

如果是自定义标签加@register.simple_tag装饰器

4、在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py

{% load my_tag %}

5、使用simple_tag和filter(如何调用)

<!--i=100-->
<p>{{ i|multi:2 }}</p>
<p>{% multiTag i 5 2 %}</p>

<!-- 自定义标签不能用到 if 和 for 标签中 -->
{% if i|multi:5 > 1000 %}
    <p>大于</p>
{% else %}
    <p>小于或等于</p>
{% endif %}

6、对比过滤器与自定义标签的使用:
过滤器函数的参数只能有两个,自定义标签无参数限制
过滤器可以与逻辑标签共同使用,比如if标签。自定义标签不可以。


 

七、模版继承

明日更新。。。

祝各位路友节日快乐

 

63、django之模版层(template)

标签:原因   部门   翻译   hello   开会   ons   tin   text   rom   

原文地址:http://www.cnblogs.com/liluning/p/7724699.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!