模板简单梳理

# 查找路径

项目的settings.py文件中的TEMPLATES配置包含模板引擎配置、模板查找路劲配置、模板上下文配置等;配置路径的两个位置:

  1. DIRS :在该列表中存放所有的模板路径,在视图中使用render或者render_to_string渲染模板在该列表中查找模板路径;
  2. APP_DIRS :默认为True。会在INSTALLED_APPS中安装的APP下的templates文件中查找模板;
  • 查找顺序:DIRS --> 已安装的当前APP下的templates文件中 --> 其它APP --> 没找到抛出异常(TemplateDoesNotExist)模板简单梳理  

# 模版变量

  1. 在模版中使用变量,需要将变量放到 {{ 变量 }} 中。
  2. 如果想要访问对象的属性,那么可以通过 对象.属性名 来进行访问。
     1 ```
     2 class Person(object):
     3     def __init__(self,username):
     4         self.username = username
     5 
     6 def index(request):
     7     context = {
     8     'person': p
     9 }
    10 ```

    要访问`person`的`username`,那么在 html 文件就是通过 {{ person.username }} 来访问。

  3. 如果想要访问一个字典的key对应的value,那么只能通过 字典.key 的方式进行访问,不能通过 中括号[ ] 的形式进行访问。
    1 ```
    2 context = {
    3     'person': {
    4         'username':'jack'
    5     }
    6 }
    7 ```

    在模版中访问`username`。使用代码 person.username 

  4. 因为在访问字典的`key`时候也是使用 点. 来访问,因此不能在字典中定义字典本身就有的属性名当作`key`,否则字典的那个属性将编程字典中的key。
  5. 如果想要访问列表或者元组,那么也是通过 点. 的方式进行访问,不能通过 中括号[ ] 的形式进行访问。这一点和python中是不一样的
    1 ```
    2 {{ persons.1 }}
    3 ```

#  标签

 if  标签:

  1. 所有的标签都是在  {% %}  之间。
  2. 有闭合标签{% endif %} 。
  3. 判断运算符,跟python中的判断运算符是一样的。`==、!=、<、<=、>、>=、in、not in、is、is not`这些都可以使用。
  4. 还可以使用 elif 以及 else 等标签。

 for...in... 标签:

  1. 类似于`Python`中的`for...in...`。可以遍历列表、元组、字符串、字典等一切可以遍历的对象。
    1 ```html
    2 {% for person in persons %}
    3     <p>{{ person.name }}</p>
    4 {% endfor %}
    5 ```
  2. 如果想要反向遍历,那么在遍历的时候就加上一个 reversed 。
    1 ```
    2 {% for person in persons reversed %}
    3     <p>{{ person.name }}</p>
    4 {% endfor %}
    5 ```
  3. 遍历字典的时候,需要使用`items`、`keys`和`values`等方法。在`DTL`中,执行一个方法不能使用圆括号的形式。
    1 ```python
    2 {% for key,value in person.items %}
    3     <p>key:{{ key }}</p>
    4     <p>value:{{ value }}</p>
    5 {% endfor %}
    6 ```

在 for 循环中,`DTL`提供了一些变量可供使用。这些变量如下:

  • forloop.counter:当前循环的下标。以1作为起始值。
  • forloop.counter0:当前循环的下标。以0作为起始值。
  • forloop.revcounter:当前循环的反向下标值。比如列表有5个元素,那么第一次遍历这个属性是等于5,第二次是4,以此类推。并且是以1作为最后一个元素的下标。
  • forloop.revcounter0:类似于forloop.revcounter。不同的是最后一个元素的下标是从0开始。
  • forloop.first:是否是第一次遍历。
  • forloop.last:是否是最后一次遍历。
  • forloop.parentloop:如果有多个循环嵌套,那么这个属性代表的是上一级的for循环。
    • 模板中的for...in...没有continue和break语句,这一点和Python中有很大的不同,一定要记清楚!

for...in...empty 标签:

  • 与`for...in...`一样,只不过在遍历的对象如果没有元素的情况下,会执行 empty 中的内容。
    1 '''
    2 {% for other in others %}
    3     <li>{{ other }}</li>
    4 {% empty %}
    5     <li>点个赞吧!!!</li>
    6 {% endfor %}
    7 '''

 with  标签:

  • 使用with定义变量: with xx=xxx 与  with xxx as xx 两种形式,内容需包含在 with 语句块中
    1 '''
    2 {% with b=comments %}
    3     <p>{{ b }}</p>
    4 {% endwith %}
    5 
    6 {% with comments as a %}
    7     <p>{{ a }}</p>
    8 {% endwith %}
    9 '''

      

 url 标签:

  1. 使用实例命名空间来对 url 进行反转。
    1 '''
    2 <ul>
    3     <li><a href="{% url 'books' %}">图书</a></li>
    4 </ul>
    5 '''
  2. `url`反转的时候需要传递参数,可以在后面传递。参数分位置参数和关键字参数,位置参数和关键字参数不能同时使用。
     1 '''
     2 # path部分
     3 path('detail/<book_id>/',views.book_detail,name='detail')
     4 
     5 # url反转,使用位置参数
     6 <a href="{% url 'book:detail' 1 %}">图书详情页面</a>
     7 
     8 # url反转,使用关键字参数
     9 <a href="{% url 'book:detail' book_id=1 %}">图书详情页面</a>
    10 '''
  3. 反转的时候要传递查询字符串的参数,须要手动在后面添加。
    1 '''
    2 <li><a href="{% url 'login' %}?next=/">登录</a></li>
    3 '''
  4. 需要传递多个参数,通过空格的方式进行分隔。
    1 '''
    2 <li><a href="{% url 'book' book_id=1 category=2 %}">图书ID及分类</a></li>
    3 '''

# autoescape

  • 自动转义, DTL 中默认开启自动转义,如 < 转义为 &lt; 等,可使用标签进行关闭
     1 '''views.py文件
     2 context = {    
     3     'info':"<a href='http://www.baidu.com'>百度</a>"
     4 }
     5 '''
    1 '''html文件
    2 {% autoescape off %}
    3     {{ info }}
    4 {% endautoescape %}
    5 '''
    1 #不使用autoescape标签时网页输出'info'对应的字符串,而不是‘超链接’:百度
    2 <a href='http://www.baidu.com'>百度</a>

# verbatim标签

  •  DTL 模板会默认解析特殊字符,如 {% , %} 以及 {{ 等字符,使用该标签让其不进行解析
    1 '''
    2 {% verbatim %}
    3     {{ info }}
    4 {% endverbatim %}
    5 '''
    6 #网页输出{{ info }},而不是解析后‘hello’所对应的值

# 过滤器

  •  add :将参数添加到原来的值上,整数相加,字符串与列表进行拼接
     1 from django.shortcuts import render
     2 
     3 def index(request):
     4     context = {
     5         'value1':['1','2'],
     6         'value2':['3','4']
     7     }
     8     return render(request,'index.html',context)
     9 
    10 '''index.html
    11     {{ value1|add:value2 }}    #拼接
    12     {{ '1'|add:2 }}    #相加
    13 '''
  •  cut :移除所指字符串,类似于python的 replace(arg,“”) 
    1 '''
    2 context = {
    3     'name':'hello world'
    4 }
    5 '''
    6 '''html
    7 {{ name|cut:' ' }}    #移除空格
    8 '''
  •  date  :将一个日期按指定格式,格式化为一个字符串
    '''
    context = {
        'today':datetime.now()    #获取当前时间
    }
    '''
    <body>
        {{ today|date:'Y-m-d H:i:s' }}
    </body>
  •  default :在被 if 判断为 False 的值时,可提供默认值 value|default:'nothing' ;
  •  default_if_none :只有当值为 None 时才使用默认值;
  •  first / last :返回对应值的第一个或最后一个值;
  •  floatformat :使用四舍五入的方式格式化一个浮点类型,没参数时小数位默认保留一位,为0时保留整数;
    1 {{ value|floatformat:3}}
    2 #小数位默认保留三位
  •  join :将列表、元组、字符串使用指定字符拼接;
  •  lenght :获取长度;
  •  lower / upper :转换小写或大写;
  •  random :随机获取一个值;
  •  safe :关闭字符串的自动转义,与 {% autoescape off %} 一样;
  •  slice :类似于python的切片操作 {{ value|splice“1::2” }} ;
  •  striptags :删除字符串出现的HTML标签;
  •  truncatechars :定义字符串的长度,超过的字符进行切割后用 ... 进行代替,本身占用三个字符 {{ value|truncatechars:3 }} ;
  •  truncatechars_html :只切割字符串,保留HTML标签且不计算其长度 
    1 {{ value|truncatechars_html:5 }} 
    2 #<p>尊敬的...</p>

# 模板优化

  • 使用include标签
  1. 对于不同页面重复的代码,可新建一个模板进行存储,后再使用 include 进行引用;
     1 <!--每个页面都会显示的头部内容-->
     2 <body>
     3     <header>
     4         <ul>
     5             <li><a href="{% url 'index' %}">首页</a></li>
     6             <li><a href="{% url 'company' %}">公司</a></li>
     7             <li><a href="{% url 'school' %}">学校</a></li>
     8             <li>{{ username }}</li>
     9         </ul>
    10     </header>
    11 </body>
    12 <!--username:为index.html文件的参数,只在映射index的模板中显示,公司与学校的页面无法显示该内容-->
  2. 使用 include 子模板时,可使用 with xx=‘xxx’ 来引用其参数值进行显示,如上方的学校页面要显示username的内容时需传递参数:
    1 #views.py的index函数包含参数
    2 '''
    3 def index(request):
    4     context = {
    5         'username':'jack'
    6     }
    7     return render(request,'index.html',context)
    8 '''
    1 <!--学校模板:使用‘with’传入参数可显示内容-->
    2 <body>
    3     {% include 'header.html' with username='jack' %}
    4     <div class="content">
    5         这是学校内容
    6     </div>
    7     {% include 'footer.html' %}
    8 </body>
  • 模板继承
  1. 类似于python的类,可先在一个模板中定义好父模板的内容,然后给其他模板进行继承使用
     1 <!--base.html 父模板-->
     2 <header>
     3         <ul>
     4             <li><a href="{% url 'index' %}">首页</a></li>
     5             <li><a href="{% url 'company' %}">公司</a></li>
     6             <li><a href="{% url 'school' %}">学校</a></li>
     7             <li>{{ username }}</li>
     8         </ul>
     9 </header>
    10 <!--使用‘block’可让子模板渲染内容-->
    11 {% block title %}
    12     标题
    13 {% endblock %}
    14 
    15 <div class="content">
    16     {% block content %}
    17 
    18     {% endblock %}
    19 </div>
    20 <footer>
    21     这是尾部内容
    22 </footer>
  2. 子模板通过 {% extends %} 标签来进行继承,该标签需放在模板最开始的位置。子模板的代码需放在 block 中才能被渲染,对于父模板中 block 的代码内容需使用 {{ block.super }} 标签才能显示出来。
    1 <!--子模板-->
    2 {% extends 'base.html' %}
    3 {% block title %}
    4     {{ block.super }}内容
    5 {% endblock %}
    6 {% block content %}
    7     这是首页的代码
    8 {% endblock %}

# 加载静态文件

  使用 static 标签来加载静态文件。

  • 加载静态文件的步骤:
  1. 确保 settings.py 文件的 settings.INSTALLED_APPS 添加了 django.contrib.staticfiles 以及末尾设置了  STATIC_URL = '/static/'
  2. 在已经安装了的`app`下创建一个文件夹 static ,然后该文件夹下创建一个与当前`app`名字一样的文件夹,把静态文件放到该文件夹下。(防止多个`app`之间有同名的静态文件而产生混淆)
  3. 当静态文件不放在`app`中时。可在 settings.py 中添加 STATICFILES_DIRS 并在根目录下新建存储的文件, DTL 会根据该路径查找静态文件。
    1 #路径名:static
    2 STATICFILES_DIRS = [
    3 os.path.join(BASE_DIR,"static")
    4 ]
  4. 在模版中使用 load 标签加载 static 标签。加载在项目的 static 文件夹下的 style.css 文件
    1 ```html
    2 {% load static %}
    3 <link rel="stylesheet" href="{% static 'style.css' %}">
    4 ```
    1 <!--加载‘front’应用的static文件下的静态文件-->
    2 <body>
    3 <img src="static 'front/logo.jpg'" alt="">
    4 </body>
  5. 可在settings.py中的TEMPLATES/OPTIONS添加'builtins':['django.templatetags.static'],以后在模版中就可以直接使用static标签,不再load加载。
  • 如果没有添加 django.contrib.staticfiles 。则需要手动将请求静态文件的`url`与静态文件的路径进行映射了
    1 ```python
    2 from django.conf import settings
    3 from django.conf.urls.static import static
    4 
    5 urlpatterns = [
    6 # 其他的url映射
    7 ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    8 ```