Python学习---django模板语法180122

django模板语法[Template]

模版的组成

 HTML代码+逻辑控制代码  <h1> {{ user_name }} </h1>

逻辑控制代码的组成

1.变量: {{ 双大括号来引用变量} }

2.tag标签: {% 大括号和百分比的组合来表示使用tag  %}

3.自定义filter和simple_tag

4. extend模板继承

django模板之Template和Context对象

render(request, "hhh.html", {"name","hhh"})   

             hhh.html: 实际上是Template对象实例

            {"name","hhh"}: 实际上是Context对象实例

Django 模板解析非常快捷。 大部分的解析工作都是在后台通过对简短正则表达式一次性调用来完成。

注意: 同一模板,多个上下文,

Template原理解释

>>>python manage.py shell
>>> from django.template import Context, Template
>>> t = Template('My name is {{ name }}.')
>>> c = Context({"name":"FTL"})
>>> t.render(c)
'My name is FTL.'

image

同一模板,多个上下文,一旦有了模板对象,你就可以通过它渲染多个context,无论何时我们都可以像这样使用同一模板源渲染多个context,只进行 一次模板创建然后多次调用render()方法渲染会更为高效

t = Template('Hello, {{ name }}')
for name in ('world', '2018', '2020'):
    print t.render(Context({'name': name}))

总结一下

1. 可以使用类似Py里面的字符串拼接,返回HTTPResponse进行渲染

           html="<html><body>现在时刻:<h1>%s.</h1></body></html>" %now

2. 可以使用Template和Context对象,调用render方法后返回HttpResponse进行渲染

          html=t.render(c)

3. 可以利用Django提供的render方法,返回一个HTML文本进行渲染

          return render(req, 'current_datetime.html', {'current_date':now})

重点学习

Django 模板中遍历复杂数据结构的关键是句点字符【.】

def template1(request):
    s = 'hello world'
    ss = [1, 2, 3, 4, 5]                  # {{ tmp.2  }}    --> 2
    sss = {"name": "FTL", "age": 23 }     # {{ tmp.name }}  --> FTL
    now = datetime.datetime.now()         # {{ now.year }}  --> 2020  取对象属性
    per = Person('FTL', 23)               # {{ per.name }}  --> FTL   取类属性
    return render(request, 'template_juhao.html', {"tmp": sss})

深度变量的查找------- {% if %} 的使用

{% if %}标签计算一个变量值,如果是“true”,即它存在、不为空并且不是false的boolean值,系统则会显示{% if %}和{% endif %} 间的所有内容

{% if %} 标签接受and,or或者not来测试多个变量值或者否定一个给定的变量
      {% if %} 标签不允许同一标签里同时出现and和or,否则逻辑容易产生歧义,例如下面的标签是不合法的:
                     {% if obj1 and obj2 or obj3 %}

{% if True %}
    <p>hello world</p>
{% elif 1 %}
    <p>hello world 2</p>
{% endif %}    {# 注意闭合标签 #}

深度变量的查找------- {% for %} 的使用

# 打印列表
{% for i in list %}
    <p>{{ i }}</p>  {# 直接打印list里面的值 #}
    <p>{{ forloop.counter }}:{{ i }}</p> {# 打印下标和下表对应的值,从0开始 #} 1:1, 2:2
    <p>{{ forloop.revcounter}}:{{ i }}</p> {# 反打下标和下表对应的值,从5开始 #} 5:1,4:2
{% endfor %}
#  打印字典
{% for i in keyvalue %}
    <p>{{ i }}:{{ keyvalue.age}}</p>  {# 直接打印keyvalue里面的key #}  age:23
    <p>{{ forloop.counter }}:{{ i }}:{{ keyvalue.age}}</p>   {# 打印下标和下表对应的值,从1开始 #} 1:age:23
    <p>{{ forloop.revcounter}}:{{ i }}:{{ keyvalue.age}}</p> {# 反打下标和下表对应的值,从结尾开始 #}2:age:23
{% endfor %}

深度变量的查找------- {% for %} 的使用

深度变量的查找------- {% filter %} 的使用

语法格式:{{obj|filter:param}}

filter部分的函数:

# 1  add          :   给变量加上相应的值
# 2  addslashes   :    给变量中的引号前加上斜线
# 3  capfirst     :    首字母大写
# 4  cut          :   从字符串中移除指定的字符
# 5  date         :   格式化日期字符串
# 6  default      :   如果值是False,就替换成设置的默认值,否则就是用本来的值
# 7. autoescape off:   告诉浏览器,括号内的内容是可以渲染的
# 8. safe          :   告诉浏览器,传递的内容是安全的可以直接渲染
# 9  default_if_none:  如果值是None,就替换成设置的默认值,否则就使用本来的值 

obj作为一个对象传递给filter:filter参数

{#obj作为一个对象传递给filter:filter参数#}
{{ obj|upper }}        {# HELLO WORLD #}<hr>
{{ obj|lower }}        {# hello world #}<hr>
{{ obj|first|upper }}  {# H #}<hr>
{{ obj|capfirst }}     {# Hello world #}<hr>
{{ obj|cut:' ' }}      {# helloworld #}<hr>  
{{ obj|add:5 }}        {# 数字类型进行加法运算 #}<hr>
{{ ojb|date:'Y-m-d' }}    {# 格式化输出日期 #}<hr>
{{ obj|default:'空的' }}  {# 有则显示,无责显示空的 #}<hr>
{#obj="https://www.baidu.com"#}
{{ obj |urlencode }} {# url编码 #}<hr>
{#  obj = '<a href="#">跳转</a>' #}
    {% autoescape off %}
        {# 如果不用autoescape off,则直接显示原来的文本内容 #}
        {# 这里使用autoescape off后,则浏览器会直接渲染 #}
        {{ obj }}
    {% endautoescape %}
=====> endautoescape 可以用 {{ obj|safe }} 代替

深度变量的查找------- {%csrf_token%}:csrf_token标签

          csfr_token仅仅适应form表单,用于生成csrf_token的标签,用于防治跨站攻击验证。

         其实,这里是会生成一个input标签,和其他表单标签一起提交给后台的。

注意:如果在view的index里用的是render_to_response方法,不会生效

settigs.py

'DIRS': [os.path.join(BASE_DIR, 'templates')],  # 设置templates的路径为Django以前版本
# 'DIRS': [],      # 注释掉该行,此为Django 2.0.1最新版本
'django.middleware.csrf.CsrfViewMiddleware', # 这里引用csrf
         ...省略默认配置
STATIC_URL = '/static/'
TEMPLATE_DIRS = (os.path.join(BASE_DIR,  'templates'),)  # 原配置
# 静态资源文件
STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),)   # 现添加的配置,这里是元组,注意逗号

templates/template1.html

<!DOCTYPE html>
<html lang="en">
<head> <meta charset="UTF-8"></head>
<body>
    <form action="/template1/" method="post">
        <input type="text" name="user">
        <input type="text" name="pwd">
        <input type="submit" value="submit">
        {# 跨站伪造请求 ,这里的csrf会翻译为一个input标签,#}
        {% csrf_token %}
    </form>
</body>
</html>

mysite2/urls.py

from django.contrib import admin
from django.urls import path
from blog import views
from django.conf.urls import url
urlpatterns = [
       # template  -- 万能的句号
       url(r'template1/', views.template1),  # 将路径名跟函数进行映射
]

views.py

from django.shortcuts import render, HttpResponse
import datetime 
def template1(request):
    if request.method == "POST":
        return HttpResponse("OK")
    return render(request, 'template1.html')

页面显示:

image

深度变量的查找----{% with %}:用更简单的变量名替代复杂的变量名

{% with total=fhjsaldfhjsdfhlasdfhljsdal %} {{ total }} {% endwith %}
 

深度变量的查找---- {% verbatim %}: 禁止render

{% verbatim %}
    {{ hello }}  {# 此处的变量hello浏览器不再进行渲染 #}
{% endverbatim %}

深度变量的查找----{% load %}: 加载标签库

注意:在HTML文件的首行添加

深度变量的查找----自定义simple_tag/filter

a、在app中创建templatetags模块(必须的)

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

c、在使用自定义simple_tag和filter的html文件首行导入之前创建的 my_tags.py :

      {% load my_tags %}

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

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

image

settigs.py

'DIRS': [os.path.join(BASE_DIR, 'templates')],  # 设置templates的路径为Django以前版本
# 'DIRS': [],      # 注释掉该行,此为Django 2.0.1最新版本
# 'django.middleware.csrf.CsrfViewMiddleware',
         ...省略默认配置
STATIC_URL = '/static/'
TEMPLATE_DIRS = (os.path.join(BASE_DIR,  'templates'),)  # 原配置
# 静态资源文件
INSTALLED_APPS = [
   ...
'blog.apps.BlogConfig',   # 配置当前的App,PyCharm默认帮我们配置好
]
STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),)   # 现添加的配置,这里是元组,注意逗号

/blog/templatetags/my_tag.py [templatetags名称固定]

from django import template
register = template.Library()   # register的名字是固定的,不可改变
@register.simple_tag
def add_2000(nu):
    return nu + 2000
@register.filter
def multiple(v1):
    return v1 * 4
@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)

templates/template1.html

{% load my_tag %}          {# 首行引用文件 #}
<!DOCTYPE html>
<html lang="en">
<head> <meta charset="UTF-8"></head>
<body>
    <h2>初始值: {{ template_num }}    </h2>
    <h2>调用系统add:
        {{ template_num|add:1000 }}  {# 调用系统的add函数 #}
    </h2>
    <h2>调用自定义的add_2000函数:
        {% add_2000 template_num  %}  {# 调用自定义的add_2000函数 #}
    </h2>
    <h2>调用自定义的filter下的multiple函数:
        {{ template_num|multiple  }}   {# 调用自定义的filter下的multiple函数 #}      
{# {{ template_num|multiple:1000 }}调用自定义filter下的multiple函数且传参数,函数未实现 #}
    {# 函数名和参数直接必须紧挨着哈#}
    </h2>
</body>
</html>

mysite2/urls.py

from django.contrib import admin
from django.urls import path
from blog import views
from django.conf.urls import url
urlpatterns = [
  url(r'template1/', views.template1),  # 将路径名跟函数进行映射
]

views.py

from django.shortcuts import render, HttpResponse
import datetime 
def template1(request):
    if request.method == "POST":
        return HttpResponse("OK")
    template_num = 1000
    return render(request, 'template1.html', {"template_num": template_num})

页面显示:

image

filter可以用于if等语句后面,simple_tag不可以

{% if num|filter_multi:30 > 100 %}
    {{ num|filter_multi:30 }}
{% endif %}

自定义filter和simple_tag的区别:

image

posted @ 2018-07-31 21:20  小a玖拾柒  阅读(1125)  评论(0编辑  收藏  举报