一、关于django模板的构成。 django模板是由HTML代码+逻辑控制代码构成的。
二、关于django模板的基本语法。
1.关于模板中的Template和Context对象,以及如何将python中的字符串列表等数据类型传递给模板的变量中。 首先,执行python3 manange.py shell (进入该django项目的环境) from django.template import Context, Template tem = Template('My name is {{ name }}.') #!创建一个模板对象。 con = Context({'name': 'ayumi'}) #!创建一个Context对象,这个对象的作用是将python程序中字符串的内容通过模板变量的形式,传递给模板对象进行渲染。 tem.render(con) #开始通过变量名为con的这个 Context对象进行渲染。 那么最后输出的结果就是:“My name is ayumi”。 在模板对象中的{{name}}就是在引用一个模板变量,这个模板变量通过django中的Context进行赋值。
在view视图中推荐的写法如下: def current_time(req):
now=datetime.datetime.now()
return render(req, 'current_datetime.html', {'current_date':now})
2.如何深度查找。 在前面的例子中,通过 context对象传递的简单参数值主要是字符串,然而,模板中的变量还可以接收和处理更复杂的数据结构类型,比如(list)列表,(dict)字典,(tuple)元祖。 如果想在django模板中遍历这些稍微复杂一些的数据类型,则可以使用(.)点号,来进行深度遍历。 (1)获取列表或者元祖中的某个元素。 from django.template import Template, Context tem = Template('bitch is {{ items.2 }}.') con = Context({'items': ['luoyufeng', 'zhouyinting', 'jolin']}) tem.render(con) ‘bitch is jolin’
(2) 获取字典中的某个元素。 from django.template import Template, Context tem = Template('name is {{ diva.name }},is {{diva.age}} years old' ) con = Context({'diva': {'name':'bitch jolin','age':'130'}) tem.render(con) ''name is bitch jolin is 130 years old"
(3)点号还可以获取对象中某个属性的值。 from django.template import Template, Context import datetime d = datetime.date(1995, 9, 5) d.year 1995 d.month 9 d.day 5 t = Template('The month is {{ date.month }} and the year is {{ date.year }}.') c = Context({'date': d}) t.render(c) 'The month is 9 and the year is 1995.'
接下来我们自定义一个类来试一下。 from django.template import Template, Context class Person(object): def init(self, first_name, last_name): self.first_name, self.last_name = first_name, last_name t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.') c = Context({'person': Person('jolin', 'Bitch')}) t.render(c) 'Hello, jolin Bitch.'
(4)点号的功能不止如此,还可以执行对象内置的方法。 from django.template import Template, Context t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}') t.render(Context({'var': 'hello'})) 'hello -- HELLO -- False' t.render(Context({'var': '123'})) '123 -- 123 -- True'
注意!!通过模板中的.点号去调用属性的内部方法,是没有办法传递参数的!!所以我们只能调用不需要传递参数的方法。
3.模板中的变量过滤器filter。 语法格式如下: {{模板变量|过滤参数}} 常用的过滤参数如下: 【1】add: 给变量加上相应的值. 【2】addslashes :给变量中的引号前面加上斜线。 【3】capfirst : 首字母大写。 【4】cut:去掉字符串中指定字符。 【5】date:格式化指定字符串。 【6】default: 如果获得的值是False,就替换成设置的默认值,否则就是用本来的值。 【7】default_if_none: 如果值是None,就替换成设置的默认值,否则就使用本来的值。 【8】ilesizeformat :将bytes转换为人类可读的大小。 【9】first:取出第一个字符。 【10】lenth:取出字符串长度。 【11】slice:按索引切片。 示例: #value1="aBcDe" {{ value1|upper }}
#value2=5 {{ value2|add:3 }}
#value3='he llo wo r ld' {{ value3|cut:' ' }}
#import datetime #value4=datetime.datetime.now() {{ value4|date:'Y-m-d' }} #value7='1234' {{ value7|filesizeformat }}<br> {{ value7|first }}<br> {{ value7|length }}<br> {{ value7|slice:":-1" }}<br> url字符转意: #value8='http://www.baidu.com/?a=1&b=3' {{ value8|urlencode }}<br>
三、模板中的常用标签。 1.模板中的if判断标签。 模板中的if判断标签,其实和python语言中的差不多,直接上例子了。 {% if num >= 100 and 8 %}
{% if num > 200 %}
<p>num大于200</p>
{% else %}
<p>num大于100小于200</p>
{% endif %}
{% elif num < 100%} <p>num小于100</p>
{% else %} <p>num等于100</p>
{% endif %}
需要注意: {% if %} 标签接受and,or或者not来测试多个变量值。 {% if %} 标签不允许同一标签里同时出现and和or,否则逻辑容易产生歧义。
2.for循环标签。 {% for %}标签允许你按顺序遍历一个序列中的各个元素,每次循环模板系统都会渲染{% for %}和{% endfor %}之间的所有内容。 格式如下: < ul > {% for obj in list %} < li>{{ obj.name }}< /li > {% endfor %} < /ul>
(1)django模板中的for循环,支持反序遍历。 实现这种反序遍历只需要在for标签中加上reversed参数即可。 {% for obj in list reversed %} ... {% endfor %}
(2)for 循环嵌套: {% for country in countries %} < h1 >{{ country.name }}</h 1> < ul> {% for city in country.city_list %} < li>{{ city }}< /li> {% endfor %} < /ul> {% endfor %} 在使用循环嵌套的时候,需要注意,django模板是不支持break中断循环或者continue语句,不过for循环标签中内置了一个forloop模板变量,在forloop这个变量中,提供了循环的相关信息。
(3)forloop变量。
【1】forloop.counter表示循环的次数,它从1开始计数,第一次循环设为1。
例:
{% for item in todo_list %}
<p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}
【2】forloop.counter0 类似于forloop.counter,但它是从0开始计数,第一次循环设为0。
【3】forloop.revcounter 与forloop.counter相反的顺序。
【4】forloop.first 当第一次循环的时候,为True。
例:
{% for object in objects %}
{% if forloop.first %}
<li class="first">
{% else %}
<li>
{% endif %}
{{ object }}
< /li>
{% endfor %}
关于forloop标签,需要注意的: 【1】forloop变量只能在循环中得到,当模板解析器到达{% endfor %}时forloop就会消失。 【2】如果模板context已经包含一个叫forloop的变量,Django会用{% for %}标签替代它。 【3】Django会在for标签的块中覆盖你定义的forloop变量的值。
3.csrf_token标签{%csrf_token%}: 这个标签的主要作用是防跨站攻击,它会生成一个input标签,和其他表单标签一起提交给后台,后面的文章会详细介绍。
4.{% url %}url标签。 这个标签在url路由配置的文章做了详细介绍,用于根据url路由规则配置的url路径来生成url路径。
< form action="{% url "bieming"%}" > < input type="text"> < input type="submit"value="提交"> {%csrf_token%} < /form>
5.{% with %} 为模板中的变量名设置别名。 例: {% with total=fhjsaldfhjsdfhlasdfhljsdal %} {{ total }} {% endwith %}
6.{% verbatim %} 禁止渲染。 在{% verbatim %}标签内的字符串,是不会被渲染的。 { % verbatim %} {{ hello }} {% endverbatim %} 这个标签的功能和转义类似。
四、自定义filter和标签。(当默认的filter和标签不好用时) 1.首先要先在自己的app中创建一个templatetags模块!!(这一步必须做!) 2.在这个模块中创建任意名称的py文件。 3.注册 例: from django import template from django.utils.safestring import mark_safe
register = template.Library() #register的名字是固定的,不可改变!!
@register.filter def filter_multi(v1,v2): return v1 * v2
@register.simple_tag def simple_tag_multi(v1,v2): return v1 * v2
@register.simple_tag def my_input(id,arg): result = "<input type='text' id='%s' class='%s' />" %(id,arg,) return mark_safe(result) 4。注册,并且写好了自定义的filter和标签之后,在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py :{% load my_tags %} 例: {% load xxx %} !!#注意!!这个要写在html模板的首行!!!
-------------------------------.html {% load xxx %} #首行
#num=12 {{ num|filter_multi:2 }} #24
{{ num|filter_multi:"[22,333,4444]" }}
{% simple_tag_multi 2 5 %} 参数不限,但不能放在if for语句中 {% simple_tag_multi num 5 %}
最后一步在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag!
补!: filter和自定义的simple_tag(标签)有一个特别大的区别,就是filter可以使用在if判断,for循环等语句后,但是simple_tag标签不可以。 {% if num|filter_multi:30 > 100 %} {{ num|filter_multi:30 }} {% endif %}