Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 韩国一级网站,久久综合九色综合97免费下载,国产精品第一页在线

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          「Django框架」-模板

          「Django框架」-模板

          源于公眾號:Python野路子

          一、模板介紹


          我們之前學習的,都是在視圖函數直接返回文本,在實際中我們更多的是帶有樣式的HTML代碼,這樣可以讓瀏覽器渲染出非常漂亮的頁面,目前市面上有非常多的模板系統,其中最常用的是DTLJinja2DTL(Django Template Language),也就是Django自帶的模板語言,當然也可以配置Django支持Jinja2,但是作為Django內置的模板語言,不會產生一些不兼容的情況,最好還是使用內置的。

          1. DTL與普通的HTML文件區別

          DTL模板是一種帶有特殊語法的HTML文件,這個HTML文件可以被Django編譯,可以傳遞參數進去,實現數據動態化,在編譯完成后,生成一個普通的HTML文件,然后發送給客戶端。

          2. 模板渲染

          可以使用render函數進行渲染,將數據渲染到指定的HTML模板中。

          我們在之前的基礎上,再新建一個articleapp,除了剛開始第一個應用,我們在pycharm創建項目的時候,填了app名字,pycharm會自動幫我們創建應用,后續如果還要再新建應用,我們都要使用命令方式才能新建app


          應用創建完成了,接下來我們需要在配置文件settings.py里面注冊應用app

          INSTALLED_APPS = [
              'django.contrib.admin',
              'django.contrib.auth',
              'django.contrib.contenttypes',
              'django.contrib.sessions',
              'django.contrib.messages',
              'django.contrib.staticfiles',
              'user.apps.UserConfig',   # 使用pycharm創建的應用,pycharm會自動注冊
              'article'  # 手工命令方式創建的應用app,需要手工在這注冊應用!
          ]
          

          路由和視圖代碼:

          # 主urls.py
          path('article/', include('article.urls', namespace='article'))
              
          # 應用urls.py,創建的應用這個文件不會自動生成,需要我們新建
          
          from django.urls import path
          from . import views
          
          app_name = 'article'
          urlpatterns = [
              path('index/', views.index, name='index')
          
          ]
          
          # 視圖views.py
          from django.shortcuts import render
          
          def index(request):
              return render(request, 'index.html')  # 使用render渲染模板
          

          模板文件,項目根目錄下templates目錄(若沒有自動生成,則手工新建此文件夾)下新建index.html模板文件。

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>文章首頁</title>
          </head>
          <body>
              <h2>文章首頁</h2>
          </body>
          </html>
          

          查看效果:

          使用render函數將模板成功渲染出來了。

          3. 模板文件查找路徑

          在項目的settings.py配置文件中,有一個TEMPLATES配置。

          TEMPLATES = [
              {
                  # 模板引擎,就是Django內置的模板引擎,
                  # 若要配置為Jinja2:django.template.backends.jinja2.Jinja2
                  'BACKEND': 'django.template.backends.django.DjangoTemplates',
                  # BASE_DIR,項目根目錄路徑下的templates查找
                  #'DIRS': [os.path.join(BASE_DIR, 'templates')] # Django2中使用
                  'DIRS': [BASE_DIR / 'templates'],  #  Django3中使用
                  ,
                  # 是否從app應用下的templates下查找模板文件
                  'APP_DIRS': True,
                  'OPTIONS': {
                      # 模板中間件
                      'context_processors': [
                          'django.template.context_processors.debug',
                          'django.template.context_processors.request',
                          'django.contrib.auth.context_processors.auth',
                          'django.contrib.messages.context_processors.messages',
                      ],
                  },
              },
          ]
          

          這個配置包含了模板引擎的配置,這個配置包含了模板引擎的配置,模板查找路徑的配置,模板上下文的配置等,模板路徑可以2個地方配置。

          1. DIRS:這是一個列表,在這個列表中可以存放所有的模板路徑,以后在視圖中使用render渲染模板時,就會從這個列表的路徑中查找模板。
          2. APP_DIRS:默認為True,這個表示已經在INSTALLED_APPS文件中注冊過的應用app下的templates目錄下查找模板文件。
          3. 查找順序:比如代碼render(request,'index.html'),先會在DIRS這個列表中依次查找路徑下有沒有這個模板,如果有,就返回,如果沒有,則會先檢查當前視圖所處的app是否已經安裝,那么就先在當前app下的templates目錄下查找模板,如果沒有找到,就會去其他注冊的app中繼續查找,如果所有路徑下都沒有找到,則會拋出TemplateDoesNotExist

          二、DTL模板語法

          1. 模板變量

          我們想要將后臺數據渲染到頁面上,這就需要用到模板變量。

          # 主urls.py
          path('article/', include('article.urls', namespace='article'))
          
          # 應用urls.py
          path('index/', views.index, name='index')
          
          
          
          # 視圖views.py
          from django.shortcuts import render
          
          class Article:
              def __init__(self, title):
                  self.title = title
          
          
          def index(request):
              context = {
                  'msg': '模板變量',    # 字符串,
                  'article': Article('Django框架之模板文件'),    # 實例一個對象,
                  'author': {'name': 'admin'},    # 一個字典
                  'tag': ['python入門', 'python進階', '數據庫']  # 列表或元組
              }
          
              return render(request, 'index.html', context=context)  # 傳入一個字典
          

          模板文件:

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>文章首頁</title>
          </head>
          <body>
              <h2>文章首頁</h2>
              <p>{{ msg }}</p> <!-- 在模板中使用變量,需要將變量放到 {{ 變量 }} 中 -->
              <h3>{{ article.title }}</h3>  <!-- 要訪問對象的屬性,通過"對象.屬性名" 訪問 -->
              <p>作者:{{ author.name }}</p>  <!-- 要訪問字典key對應值value,通過"字典.key" 訪問,不能[]形式 -->
              <ul>
                  <li>{{ tag.0 }}</li>  <!-- 要訪問列表或者元組的元素,通過"列表.索引" 訪問 -->
                  <li>{{ tag.1 }}</li>
                  <li>{{ tag.2 }}</li>
              </ul>
          </body>
          </html>
          

          效果:


          在模板中使用變量:語法:{{變量名}} 1)命名由字母和數字以及下劃線組成,不能有空格和標點符號。2)不要和python或django關鍵字重名。原因:如果data是一個字典,那么訪問data.items將會訪問data這個字典的key名為items的值,而不會訪問字典的items方法。

          2. 模板標簽

          標簽語法:{% 標簽名稱 %} {% 結束標簽名稱 %}

          例:{%tag%} {%endtag%}

          2.1 if標簽

          if標簽相當于python中的if語句,有elifelse相對應,可以使用and、or、in、not、==、!=、<=、>=、is、is not,來進行判斷。

          視圖views.py

          def index(request):
              age = random.randint(6, 20)  # 隨機生成6-20的整數
          
              context = {
                  'age': age
              }
          
              return render(request, 'index.html', context=context)
          

          模板文件:

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>文章首頁</title>
          </head>
          <body>
              <p>
                  <span>年齡:<strong>{{ age }}</strong>,</span>
                  <span>適合讀</span>
                  <span>
                      {% if age >= 18 %}
                          【大學】書籍
                      {% elif 12 < age and age < 18 %}
                          【高中】書籍
                      {% else %}
                          【小學】書籍
                      {% endif %}
                  </span>
              </p>
          </body>
          </html>
          


          再刷新一次:


          我們還可以使用ifequal/ifnotequal來比較兩個值是否相等,如:

          {% ifequal price 0 %}
              <span class="publicimg"><img src="/images/public.png"></span>
          {% else %}
              <span class="publicimg"><img src="/images/vip.png"></span>
          {% endifequal %}
          
          
          

          2.2 for...in...標簽

          for標簽相當于python中的for循環,可以遍歷列表、元組、字符串、字典等一切可以遍歷的對象。

          # 視圖views.py
          def index(request):
              context = {
                  'articles': [              # 列表
                      '21天學會Python',
                      'C++從入門到入土',
                      'Mysql從入門到跑路'
                  ],
                  'author': {             # 字典
                      'name': '老P',
                      'age': 18,
                      'sex': 'boy'
                  },
                  'artile_details': [
                      {'title': '21天學會Python', 'author': '小P', 'words': 1000},
                      {'title': 'C++從入門到入土', 'author': '中P', 'words': 2000},
                      {'title': 'Mysql從入門到跑路', 'author': '老P', 'words': 3000}
                  ]
              }
          
              return render(request, 'index.html', context=context)
          

          模板文件:

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>文章首頁</title>
          </head>
          <body>
              <ul>
                  {% for article in articles %}
                      <li>{{ article }}</li>
                  {% endfor %}
              </ul>
              <p>獲取字典鍵:</p>
              <ul>
                  {% for key in author.keys %}
                      <li>{{ key }}</li>
                  {% endfor %}
              </ul>
              <p>獲取字典值:</p>
              <ul>
                  {% for value in author.values %}
                      <li>{{ value }}</li>
                  {% endfor %}
              </ul>
              <p>獲取字典鍵值對:</p>
              <ul>
                  {% for key, value in author.items %}
                      <li>{{ key }}:{{ value }}</li>
                  {% endfor %}
              </ul>
          
              <p>文章信息列表:</p>
              <table border="1">
                  <thead>
                      <tr>
                          <th>序號</th>
                          <th>標題</th>
                          <th>作者</th>
                          <th>字數</th>
                      </tr>
                  </thead>
                  <tbody>
                      {% for article_detail in artile_details %}
                          {% if forloop.first %}   <!-- 是否第一次遍歷 -->
                              <tr style="background: red;">
                          {% elif forloop.last %}   <!-- 是否最后一次遍歷 -->
                              <tr style="background: pink;">
                          {% else %}
                              <tr>
                          {% endif %}
                              <td>{{ forloop.counter }}</td>  <!-- 當前迭代的次數,下標從1開始。-->
                              <td>{{ article_detail.title }}</td>
                              <td>{{ article_detail.author }}</td>
                              <td>{{ article_detail.words }}</td>
                          </tr>
                      {% endfor %}
                  </tbody>
              </table>
          
          </body>
          </html>
          
          <!-- 
              forloop.counter:當前迭代的次數,下標從1開始。
              forloop.counter0:當前迭代的次數,下標從0開始。
              forloop.first:返回bool類型,如果是第一次迭代,返回true,否則返回false。
              forloop.last:返回bool類型,如果是最后一次迭代,返回True,否則返回False。
          
          	forloop.revcounter         反向循環位置(列表的最后一位是l ,列表第一位是n )
          	forloop.revcounter0        反向循環位置(列表的最后一位是0 , 列表第一位是n- 1 )
          -->
          


          還有個for...in...empty,在遍歷的時候如果需要遍歷的對象沒有為空,則執行empty下的操作。

              {% for comment in comments %}  
                  {{ comment }}
              {# 在for循環之前檢查列表大小是常見的,當列表為空的時候給出特別提示,這是常見的,所以for支持可選empry來當為空時輸出 #}    
              {% empty %}   <!-- comments沒有或為空,則執行empty下的。-->
                  還沒有評論~~~
              {% endfor %}
          

          有時候可能在頁面上要用上循環幾次,可以用:

          {% for item in  'x'|ljust:'4' %}  循環四次
          {%endfor %}
          

          2.3 with標簽

          使用一個簡單地名字緩存一個復雜的變量,當你需要使用一個代價較大的方法(比如訪問數據庫)很多次的時候這是非常有用的。

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>文章首頁</title>
          </head>
          <body>
              {{ title }}
          
              {% with t1=title %}  <!-- 使用=-->
                  {{ t1 }}
              {% endwith %}
          
              {% with title as t2%} <!-- 使用as 取別名 -->
                  {{ t2 }}
              {% endwith %}
          </body> 
          </html>
          


          注意:定義的變量只能在with語句塊中使用,在with語句塊外面使用取不到這個變量。

          2.4 url標簽

          在模板中,經常要寫一些超鏈接,比如a標簽中需要定義href屬性,當然如果通過硬編碼的方式直接將這個url寫死也是可以,但是不便于以后維護,比如需要修改url地址,那涉及到的地方都要修改,因此建議使用這種反轉的方式來實現,類似于django中的reverse一樣。

          # 應用urls.py
          from django.urls import path
          from . import views
          
          app_name = 'article'
          urlpatterns = [
              path('index/', views.index, name='index'),
              path('book/', views.book, name='book'),
              path('movie/', views.movie, name='movie'),
              path('city/', views.city, name='city'),
              path('book/hot/<int:book_id>', views.hot_book, name='hot_book')
          ]
          
          # 視圖views.py
          from django.shortcuts import render, HttpResponse
          
          def index(request):
              return render(request, 'index.html')
          
          def book(request):
              return HttpResponse('讀書頁面')
          
          def movie(request):
              return HttpResponse('電影頁面')
          
          def city(request):
              return HttpResponse('同城頁面')
          
          def hot_book(request, book_id):
              return HttpResponse('最熱門文章:%d'%book_id)
          

          模板文件:

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>文章首頁</title>
              <style>
                  li{
                      list-style: none;
                      display: inline-block;
                      margin-right: 20px ;
                  }
              </style>
          </head>
          <body>
              <ul>
                  <li><a href="">首頁</a></li>
                  <li><a href="/article/book/">讀書</a></li>  <!-- url硬編碼的方式 -->
                  <li><a href="{% url 'article:movie' %}">電影</a></li> <!-- url標簽 -->
                  <li><a href="{% url 'article:city' %}">同城</a></li>
                  <li><a href="{% url 'article:hot_book' book_id=1 %}">最火文章</a></li> <!-- url標簽 傳遞參數,這個參數需要于url映射的參數名一樣,如果傳遞多個參數,則空格隔開 -->
              </ul>
          </body>
          </html>
          


          2.5 autoescape標簽

          DTL中默認已經開啟了自動轉義,會將哪些特殊字符進行轉義,比如會將<轉義成<等。

          def index(request):
              comment_info = '個人博客網站:<a href="http://www.qmpython.com"> 全民python</a>'
              context = {
                  'info': comment_info
              }
              return render(request, 'index.html', context=context)
          

          模板文件:

           <p>個人博客網站:<a href="http://www.qmpython.com"> 全民python</a></p>
           <p>
                {{ info }}   <!-- DTL默認on開啟了自動轉義,轉換成普通字符串 -->
           </p>
           <p>
               {% autoescape off %}   <!-- off關閉自動轉義,解析html標簽 -->
                  {{ info }}
               {% endautoescape %}
           </p>
          


          如果你不知道自己在干什么,最好是使用自動轉義,這樣網站才不容易出現XSS漏洞(比如有些網站進行評論的時候,發一些含惡意的js代碼,如果不進行自動轉義會進行渲染,而不會做成普通的字符串),比如我個人博客的評論就處理了。如果是可信用的,可以關閉自動轉義,比如我的文章內容是只允許我個人發表,是可信任的,所以我直接關閉。后面可以通過過濾器safe類似處理。

          2.6 verbatim標簽

          默認在DTL模板中是會去解析那些特殊字符的,比如{% %}{{ }}等,如果我們在某個代碼片段不想使用DTL的解析,那么我們可以將這段代碼放在verbatim標簽中。

          # 視圖
          def index(request):
              return render(request, 'index.html')
          
          # 模板
          <body>
              {% if msg %}
                  {{ msg }}
              {% else %}
                  沒消息
              {% endif %}
              <br>
              {% verbatim %}
                  {% if msg %}
                      {{ msg }}
                  {% endif %}
              {% endverbatim %}
          </body>
          


          這個主要是用在,有些前端模板語法layui還有vue中也使用{{}}來表示變量,這些與DTL類似,這樣就容易引起混淆,我們可以使用這個標簽,來屏蔽掉DTL的解析,而讓前端模板去解析。

          2.7 注釋標簽

          我們在HTML中經常使用<!-- 注釋內容 -->來進行注釋,在Django模板中,我們還可以使用其他注釋。

          {# 被注釋的內容 #}:將中間的內容注釋掉。只能單行注釋。
          {% comment %}被注釋的內容{% endcomment %}:可以多行注釋。
          

          這種注釋,當我們查看網頁元素的時候是看不到的,即沒有被渲染,而<!-- -->還是可以看到原樣字符串的。

          2.8 自定義簡單標簽

          1)首先,需要添加一個templatetags的文件夾, 自定義標簽必須處在已經安裝了的app(INSTALLED_APPS注冊了)中的一個名叫templatetags的包中。

          templatetags 文件夾名字不能修改,這是django規定的。

          myproject
              |——myproject
               |——__init__.py
               |——asgi.py
               |——settings.py
               |——urls.py
               |——wsgi.py
              |——templates
              |——myapp
               |——migrations
               |——templatetags
                |——__init__.py
                |——custom_tags.py
              |——manage.py
          
          

          2)在templatetags下添加一個python文件,如我這里創建一個custom_tags.py文件,在文件中添加對應的自定義標簽。

          from django import template
          
          # register的名字是固定的,不可改變
          register = template.Library()
          
          #使用裝飾器注冊自定義標簽  
          @register.simple_tag
          def curr_date(args):#args可傳參數,根據實際需求而定
              return datetime.datetime.now().strftime(args)
          

          3)在要使用自定義標簽的HTML模板中導入和使用自定義標簽文件:

          {# 加載自定義標簽所在的文件名,由于templatetags的文件名是固定的,django可以直接找到過自定義標簽文件所在的位置 #}
          {% load custom_tags %}
          
          <h3>自定義標簽</h3>
          時間日期:{% curr_date "%Y-%m-%d"%}
          

          我們再來定義簡單標簽article/templatetags/menu_tags.py

          from django import template
          
          # register的名字是固定的,不可改變
          register = template.Library()
          @register.simple_tag
          def my_menu():
              menu_list = ['首頁','項目實戰','每日一練']  
            
              return menu_list
          
          

          模板文件templates/article/my_menu.html

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>自定義簡單標簽</title>
          </head>
          <body>
          <h1>-----------菜單欄--------------</h1>
          <br/>
          {% load menu_tags %}	<!-- 導入自定義的標簽文件 -->
          
          {% my_menu as menus %}  <!-- 注意:這里需要使用as將標簽文件返回的值賦給一個變量,然后再引用!!!-->
          
          <ul>
              {% for menu in menus %}  {# 企圖使用 {% for menu in my_menu %} 是沒效果的 #}
                  <li>{{menu}}</li>
              {% endfor %}
          </ul> 
          
          </body>
          </html>
          

          視圖渲染views.py

          def test(request):
              return render(request, 'article/my_menu.html')
          


          2.9 自定義包含標簽inclusion_tag

          一種比較普遍的tag類型只是渲染其他模塊顯示下的內容,這樣的類型叫做inclusion_tag,常用的模板標簽是通過渲染其他模板顯示數據的。

          inclusion_tag作用:創建一個動態頁面文件a.html,這個頁面可以在另外一個頁面b.html中被調用,實現這個頁面a中有的功能。

          例如,上面一個導航頁面my_menu.html,基本在每個頁面中都要包含導航,如我的個人博客一樣:



          那要怎么樣呢?

          例如,我們在首頁模板中,先試下用include來引入導航模板看看(include這個后面具體學習,這里只演示作用)。

          與上面自定義簡單標簽類似,在自定義標簽文件里面自定義包含標簽:

          from django import template
          
          from article.models import Column
          
          # register的名字是固定的,不可改變
          register = template.Library()
          #使用裝飾器注冊自定義包含標簽
          @register.inclusion_tag('article/my_menu.html') #將返回值傳給my_menu.html去,可以定義name,否則使用函數名
          def my_menu():
              # menus = ['首頁','項目實戰','每日一練']
              menus = Column.objects.all()
              
              return {'menus':menus}  
          
          

          my_menu.html

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>自定義包含標簽</title>
          </head>
          <body>
          <ul>
              {% for menu in menus %}
                <li> {{menu}} </li>
              {% endfor %}
          </ul>
          </body>
          </html>
          

          調用的html頁面文件:

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>首頁</title>
          </head>
          <body>
          
          {% load menu_tags %}   <!-- 必須要先加載創建標簽的文件-->
          
          {% my_menu %}    <!-- 調用my_menu.html頁面文件,這里使用該標簽的函數名來調用-->
          
          <h1>首頁</h1>
          
          </body>
          </html>
          

          視圖渲染:

          def test(request):
          
              return render(request, 'article/index.html')
          

          2.10 人性化語義標簽

          除了上述功能性標簽外, Django 還提供了很多輔助性標簽,這些標簽只是為了使變量輸 出變得更加可讀,下面對這些標簽進行簡單介紹。首先為了使用這些標簽,需要在INSTALLED_APPS 中注冊django .contrib.humanize, 然后在模板中引用humanize:{% raw %}{% load humanize % }{% endraw %}

          apnumber

          將數字1 ~ 9 轉換為英文單詞,但是其他數字不轉換,如數字10 將被原樣輸出。示例:

          數字1 被轉換為one ;
          數字2 被轉換為two ;
          數字10 仍顯示10 ;
          

          如果當前工程語言是中文的話,數字將會被轉換為對應的漢字,例如:

          {% raw %}
          {{ 1|apnumber }}
          {{ 2|apnumber }}
          {{ 5|apnurnber }}
          {% endraw %}
          

          如果當前工程語言是中文的話,數字將會被轉換為對應的漢字,例如:

          輸出:

          一
          二
          五
          

          intcomma

          輸出以逗號分隔的數字,如4500 輸出4,500, 4500.2 輸出4,500.2 。

          intword

          以文字形式輸出數字,如1000000 輸出“ 1.0 million ”, 1200000 輸出“ 1,2 Million ” 。對于中文系統,將會輸出對應的中文,如1200000 輸出" 1.2 百萬” 。

          naturalday

          將當前日期以及前后一天輸出為today 、yesterday 和tomorrow ,而中文系統分別輸出 “今天”“昨天”和“明天” 。

          naturaltime

          對于日期時間格式,時間值與系統當前時間比較,然后輸出結果。如當前時間輸出 “ now ”, 29 秒前輸出“ 29 sec onds ago ” 。如果使用naturaltime 輸出今天、昨天、明天的話, 就會變成“現在”“ 23 小時·以后”“ 1 日之前” 。

          ordinal

          將數字轉換為序數,如l 輸出“ 1 st ”;2 輸出“ 2nd ”;3 輸出“ 3rd ” 。注意此時中文與 英文的輸出一樣。

          3. 模板過濾器

          在模板中,有時候需要對一些數據進行處理以后才能使用,一般在Python中我們是通過函數的形式來完成的,因為在DTL中,不支持函數的調用形式(),因此在模板中,則是通過過濾器來實現的,過濾器使用的是|來使用。語法:

          {{ 變量名|過濾器名:傳給過濾器的參數}}
          

          3.1 常用過濾器

          比如使用date過濾器。

          # 視圖
          from datetime import datetime
          
          def index(request):
              now_time = datetime.now()
              context = {
                  'now_time': now_time
              }
              return render(request, 'index.html', context=context)
          
          
          # 模板文件
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>文章首頁</title>
          </head>
          <body>
              {{ now_time }} <!-- 原始渲染 -->
              <br>
              {{ now_time | date:'Y-m-d H:i:s' }}  <!-- 通過過濾器,先將日期格式化,再渲染出-->
          </body>
          </html>
          


          date時間過濾器格式:

          格式字符描述示例Y4位數的年1999y2位數的年99m2位數的月01,09n1位數的月1,9,12d2位數的日01,09,31j1位數的日1,9,31g12小時制的一位數的小時1,9,12G24小時制的一位數小時0,8,23h12小時制的兩位數的小時01,09,12H24小時制的兩位數的小時01,13,24i分鐘00-59s秒00-59

          django常用過濾器:

          add:字符串相加,數字相加,列表相加,如果失敗,將會返回一個空字符串。default:提供一個默認值,在這個值被django認為是False的時候使用。比如:空字符串、None、[]、{}等。區別于default_if_none,這個只有在變量為None的時候才使用默認值。first:返回列表中的第一個值。last:返回列表中的最后一個值。date:格式化日期和時間。time:格式化時間。join:跟python中的join一樣的用法。length:返回字符串或者是數組的長度。length_is:字符串或者是數組的長度是否是指定的值。lower:把所有字符串都編程小寫。truncatechars:根據后面給的參數,截斷字符,如果超過了用表示。{{value|truncatechars:5}},如果value是等于北京歡迎您,那么輸出的結果是北京...,為啥不是北京歡迎您...呢?因為三個點也占了三個字符,所以北京 + 三個點的字符長度就是5。truncatewords:類似truncatechars,不過不會切割html標簽,{{value|truncatewords:5}},如果value是等于<p>北京歡迎您</p>,那么輸出的結果是<p>北京...</p>capfirst:首字母大寫。slice:切割列表。用法跟python中的切片操作是一樣的,區間是前閉合后開放。striptags:去掉所有的html標簽。safe:關閉變量的自動轉義,解析html標簽。floatformat:浮點數格式化。更多可以查詢官方文檔:https://yiyibooks.cn/xx/Django_1.11.6/ref/templates/builtins.html英文:https://docs.djangoproject.com/en/1.11/ref/templates/builtins/

          過濾器總結:1、作用:對變量進行過濾。在真正渲染出來之前,過濾器會根據功能處理好變量,然后得出結果后再替換掉原來的變量展示出來。2、語法:{{greeting|lower}},變量和過濾器中間使用管道符號”|”進行使用。3、可以通過管道符號進行鏈式調用,比如實現一個功能,先把所有字符變成小寫,把第一個字符轉換成大寫,如{{message|lower|capfirst}}

          4、過濾器可以使用參數,在過濾器名稱后面使用冒號”:”再加上參數,比如要把一個字符串中所有的空格去掉,則可以使用cut過濾器,代碼如下{{message|cut:" "}},冒號和參數之間不能有任何空格,一定要緊挨著。

          3.2 自定義過濾器

          雖然DTL給我們內置了許多好用的過濾器,但是有些時候還是不能滿足我們的需求,因此Django給我們提供了一個接口,可以讓我們自定義過濾器,實現自己的需求。

          步驟:

          1、首先在某個應用app中,創建一個python包,叫做templatetags,注意名字不能改動,不然找不到。

          2、在這個templatetags包下創建一個python文件用來存儲過濾器。

          3、在新建的python文件中,定義過濾器(也就是函數),這個函數的第一個參數永遠是被過濾器的那個值,并且如果在使用過濾器的時候傳遞參數,那么還可以定義另外一個參數,但是過濾器最多只能有2個參數。

          4、自定義完過濾器,要使用django.template.Library.filter進行注冊。

          5、過濾器所在app所在app需要在settings.py中進行注冊。

          6、在模板中使用load標簽加載過濾器所在的python包。

          7、在模板中使用自定義的過濾器。

          我們來實現一個朋友圈,或者文章發表時間顯示的過濾器:

          # 自定義過濾器 date_filter.py
          from django import template
          
          from datetime import datetime, timedelta
          
          # 將注冊類實例化為register對象
          # register=template.Library() 創建一個全局register變量,它是用來注冊你自定義標簽和過濾器的,只有向系統注冊過的tags,系統才認得你。
          # register 不能做任何修改,一旦修改,該包就無法引用
          register = template.Library()
          
          # 使用裝飾器注冊自定義過濾器
          @register.filter
          def date_filter(value):
              # 判斷一下,是不是時間日期類型
              if not isinstance(value, datetime):
                  return value
          
              now = datetime.now() + timedelta(hours=8)  # 將UTC時間轉為本地時間
          
              # total_seconds()是獲取兩個時間之間的總差
              timestamp = (now - value).total_seconds()
          
              if timestamp < 60:
                  return '剛剛'
              elif 60 <= timestamp < 60*60:   # sec >= 60 and sec < 60*60
                  mint = int(timestamp / 60)
                  return '{}分鐘前'.format(mint)
              elif 60*60 <= timestamp < 60*60*24:
                  hour = int(timestamp / 60 / 60)
                  return '{}小時前'.format(hour)
              elif 60*60*24 <= timestamp < 60*60*24*2:
                  return '昨天'
              else:
                  return timestamp.strftime('%Y-%m-%d %H:%M:%S')
          
          
          # 視圖views.py
          from django.shortcuts import render, HttpResponse
          
          from datetime import datetime
          
          def index(request):
              context = {
                  'public_time': datetime(year=2020, month=3, day=23, hour=23, minute=0, second=0)
              }
              print(context)
              return render(request, 'index.html', context=context)
          
          
          
          # 模板文件
          {% load date_filter %}
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>文章首頁</title>
          </head>
          <body>
              {{ public_time|date_filter }}
          
          </body>
          </html>
          


          4. 模板結構化優化

          4.1 引入模板

          有時候一些代碼是在許多模板中都用到的,如果每次都重復的去拷貝代碼那肯定不符合項目的規范,一般我們可以把這些重復性的代碼抽取出來,就類似于Python的函數一樣,以后想要使用這些代碼的時候,就通過include包含進來,這個標簽就是include。比如大多數網頁都有頂部,中間,底部,可能進入任何頁面頂部和底部都是一樣的,只有中間部分內容不同,這個時候頂部和底部,我們就可以通過include包含起來。


          # 頂部,header.html
          <header>
              <ul>
                  <li>首頁</li>
                  <li>Python教程</li>
                  <li>Python Web開發</li>
                  <li>Python爬蟲</li>
              </ul>
              <p>用戶名:{{ username }}</p> <!-- 用于測試是否傳參 -->
          </header>
          
          # 底部,footer.html
          <footer>
              <div>?2019<a href="/">全民python</a> | 
                  <a href="http://beian.miit.gov.cn" rel="nofollow">粵ICP備18143893號</a> | 
              </div>
          </footer>
          
          # 首頁,index.html
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>文章首頁</title>
              <style>
                  div{
                      margin: 10px;
                  }
              </style>
          </head>
          <body>
            {% include 'header.html' with username='全民python' %}  <!-- 引入模板,并用with傳遞參數 -->
            <div>
              這是中間內容
            </div>
            {% include 'footer.html' %}
          </body>
          </html>
          

          視圖:

          def index(request):
              return render(request, 'index.html')
          


          我們使用include標簽時,如果引入的html代碼中需要傳入變量,則需要在所引入的view視圖中獲取變量,如果引入的html代碼中的變量是一個公共變量,則需要重復獲取N次,使用自定義包含標簽inclusion_tag,可以在定義文件中獲取一次即可。

          templates/article/my_menu.html

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>自定義簡單標簽</title>
          </head>
          <body>
          <h1>-----------菜單欄--------------</h1>
          <br/>
          {% load menu_tags %}	<!-- 導入自定義的標簽文件 -->
          
          {% my_menu as menus %}  <!-- 注意:這里需要使用as將標簽文件返回的值賦給一個變量,然后再引用!!!-->
          
          <ul> 
              {% for menu in menus %} {# 企圖使用 {% for menu in my_menu %} 是沒效果的 #}
                  <li>{{menu}}</li>
              {% endfor %}
          </ul> 
          
          </body>
          </html>
          

          article/templatetags/menu_tags.py

          from django import template
          from article.models import Column
          
          # register的名字是固定的,不可改變
          register = template.Library()
          @register.simple_tag
          def my_menu():
              #menu_list = ['首頁','項目實戰','每日一練']  
              menu_list = Column.objects.all()
            
              return menu_list
          

          templates/article/index.html

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>首頁</title>
          </head>
          <body>
          
          {% include 'article/my_menu.html' %}
          
          <h1>首頁</h1>
          
          </body>
          </html>
          


          兩者感覺效果一樣。

          4.2 模板繼承

          對于模板的重復利用,除了使用include標簽引入,還有另外種方式來實現,那就是模板繼承。模板繼承類似于Python中的類,在父類中可以先定義好一些變量和方法,然后在子類中實現,模板繼承也可以在父模板中先定義好一些子模板需要用到的代碼,然后子模板直接繼承就可以了,并且因為子模板肯定有自己的不同代碼,因此可以在父模板中定義一個block接口,然后子模板再去實現。

          我們將上面那個例子,使用模板繼承改寫下,將固定不變的頂部和底部,放在父模板中,中間變動的部分,子模板去實現。

          <!-- 父模板-->
          
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>{% block title %}全民python{% endblock %}</title>
              <style>
                  *{
                      margin: 0;
                      padding: 0;
                  }
                  header,footer{
                      background: black;
                      height: 60px;
                      width: 100%;
                      color: white;
                      text-align: center;
                      line-height: 40px;
                  }
                  footer{
                      height: 90px;
                      line-height: 90px;
                      position: absolute;
                      bottom: 0;
                  }
                  ul li{
                      list-style: none;
                      float: left;
                      margin: 20px;
                  }
                  #loginbox{
                      width: 400px;
                      height: 200px;
                      border: 1px solid red;
                      margin: 90px auto;
                      text-align: center;
                  }
              </style>
          </head>
          <body>
              <header>
                 <ul>
                     <li>首頁</li>
                     <li>編程語言</li>
                     <li>項目實戰</li>
                     <li>每日一學</li>
                  </ul>
              </header>
              <div class="content">
                  {% block content %}
                      這是子模板自己實現的部分
                  {% endblock %}
              </div>
              <footer >
                  這是footer部分
              </footer>
          </body>
          </html>
          
          
          <!-- 子模板-->
          {% extends 'base.html' %}  <!-- extends必須是模板中的第一個出現的標簽 -->
          {% block title %}{{ block.super }}-登錄界面{% endblock %} <!-- block.super繼承父類的內容,否則會覆蓋父類內容 -->
          {% block content %}
              <div id="loginbox">
                  <br/>
                  <h2>登錄界面</h2>
                  <br/>
                  <form>
                      帳 號:<input type="text">
                      <br/>
                      <br/>
                      密 碼:<input type="password">
                      <br/>
                      <br/>
                      <input type="submit" value="登錄">
                          
                      <input type="button" value="注冊">
                  </form>
              </div>
          {% endblock %}
          

          視圖函數:

          def index(request):
              return render(request, 'index.html')
          

          效果展示:


          總結:

          1. 模板繼承使用extends標簽實現,通過使用block來給子模板開放接口;
          2. extends必須是模板中第一個出現的標簽;
          3. 子模板中的內容必須放在父模板定義好的block中,否則將不會被渲染;
          4. 如果在某個block中需要使用父模板的內容,那么可以使用{{ block.super }}來繼承;
          5. 子模板決定替換的block塊,無須關注其它部分,沒有定義的塊即不替換,直接使用父模板的block塊;
          6. 除了在開始的地方定義名字,我們還可以在結束的時候定義名字,如{% block title %}{% endblock %},這樣在大型模板中顯得尤其有用,能讓我們快速看到block所包含的開始和結束。

          模板引入與自定義inclusion_tag的區別:模板導入的頁面內容是靜態的、不變的,而通過自定義inclusion_tag導入的頁面文件可以是動態的,可動性自己掌控。

          5. 加載靜態文件

          在一個網頁中,不僅僅只有一個html,還需要css樣式,js腳本以及一些圖片,因此在DTL中加載靜態文件是一個必須要解決的問題,在DTL中,使用static標簽來加載靜態文件,要使用static標簽,首先需要{% load static %}

          1、首先,settings.py文件中,確保django.contrib.staticfiles已經添加到INSTALLED_APPS中。

          INSTALLED_APPS = [
              ...
              'django.contrib.staticfiles',
              ...
          ]
          

          2、設置DEBUG調試模式。

          # 在settings.py中,默認值是DEBUG = True
          DEBUG = True
          

          當我們在開發django應用時如果設置了 DEBUG=True,那么django便會自動幫我們對靜態文件進行路由;但是當我們設置DEBUG=False后,靜態文件找不到了,「img、css、js」都提示404,無法準確的訪問 static 靜態文件。

          3、在開發模式下(Debug=True)時,訪問靜態文件有下面兩種情況:1)在已注冊的應用app下創建一個靜態文件夾名稱static,然后再再這個static目錄下創建于app同名的 文件夾用于存放靜態文件(避免不同應用app,靜態文件名字一樣,造成沖突)。

          Django將通過 django.contrib.staticfiles在每個appstatic文件夾中為我們自動查找這些靜態文件。

          2)如果有些靜態文件和應用沒什么太大的關系,我們可以在項目根目錄下再創建static目錄,這個時候我們還需要在settings.py文件配置添加STATICFILES_DIRS,以后DTL就會在這個列表的路徑中查找靜態文件。

          # django2.x方式
          # STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]  # 這里指靜態文件保存哪個目錄下,這個“static”指目錄名
          
          # django3.x方式
          # 一般用來設置通用的靜態資源,對應的目錄不放在APP下,而是放在Project下,例如:
          STATICFILES_DIRS = [BASE_DIR / 'static']
          
          

          然后再像上面一樣加載靜態文件使用,一般直接在根項目下新建static,然后在下面新建不同以應用名稱命名的目錄。

          STATICFILES_DIRS告訴django,首先到STATICFILES_DIRS里面尋找靜態文件,其次再到各個appstatic文件夾里面找(注意,django查找靜態文件是惰性查找,查找到第一個,就停止查找了)。

          4、只有在生產模式(Debug=False)時,STATIC_ROOT設置才生效。

          STATIC_ROOT 是在部署靜態文件時(pyhton manage.py collectstatic)所有的靜態文靜聚合的目錄,STATIC_ROOT要寫成絕對地址,如下例子STATIC_ROOT設為根目錄下的static_new文件,而STATICFILES_DIRS使用根目錄下的static目錄。

          #STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]  # 這里指靜態文件保存哪個路徑,這個“static”指目錄名
          STATICFILES_DIRS = [BASE_DIR / 'static']
          
          if not DEBUG:
              #STATIC_ROOT = os.path.join(BASE_DIR, "static_new") #使用 collectstatic后收集的靜態文件的存放絕對路徑
              STATIC_ROOT = [BASE_DIR / 'static_new']
          

          當部署項目時,在終端輸入:

          # django會把所有的static文件都復制到STATIC_ROOT文件夾下
          python manage.py collectstatic
          


          然后可以看到根目錄下有創建了一個static_new文件夾,里面有STATICFILES_DIRS里設置的文件夾里的靜態文件,同時也有各appstatic文件夾里的靜態文件。

          在部署模式(Debug=False)時,Django會從STATIC_ROOT設置的文件夾讀取靜態文件,而不再從STATICFILES_DIRS設置的文件夾或app下的static文件夾。所以在(Debug=False)時需要先python manage.py collectstatic同步一下靜態文件。

          說明:真實上生產,靜態文件可能就交給nginx了,配置好即可,就不會再從django里面讀取靜態文件了。具體后續我們會細說

          5、上面我們已經配置好靜態文件了,那怎么樣訪問呢?

          如果在瀏覽器是訪問,不可能輸入你的靜態文件的本地絕對地址吧,比如我的一種圖片的本地地址為 /root/src/project/QmpythonBlog/static/image/article/article_cover.png,那我們不可能

          在瀏覽器上直接輸入:http://127.0.0.1:5044/root/src/project/QmpythonBlog/static/image/article/article_cover.png 這樣子,瀏覽器會報錯, 沒有該頁面,那么django是如何讓瀏覽器也可以訪問服務器上的靜態文件呢?

          上面已經說了,直接訪問服務器本地的地址是不行的,那就需要一個映射。

          django利用STATIC_URL來讓瀏覽器可以直接訪問靜態文件。

          settings.py文件中確保配置了STATIC_URLSTATIC_URL用于引用STATICFILES_DIRSSTATIC_ROOT所指向的靜態文件。

          當我們創建Django項目的時候,在setting.py中默認就已經設置了。

          # 靜態文件存儲,一般是我們的JS、css、系統的圖片文件等。
          # 這個“static”指訪問靜態文件,引入時用的別名
          # 通過http://127.0.0.1/static/***就可以訪問相關的靜態文件了。
          
          STATIC_URL = '/static/'
          

          例如:在應用user下新建static目錄,再在static下新建user目錄:


          視圖:

          # user應用下的視圖views.py
          
          def index(request):
              return render(request, 'user/index.html')
          

          模板文件:

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>用戶登錄首頁</title>
          </head>
          <body>
              <p>用戶界面</p>
              <img src="/static/user/img/logo.png">  <!-- 如果配置文件是 STATIC_URL='/abc/',則這里url:/abc/user/img/logo.png-->
          </body>
          </html>
          

          但是上面要寫絕對路徑不方便,那我們可以通過static標簽來加載靜態文件:

          {% load static %}
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>用戶登錄首頁</title>
          </head>
          <body>
              <p>用戶界面</p>
          {#    <img src="/static/user/img/logo.png">#}
          
              <img src="{% static '/user/img/logo.png' %}"> <!-- 通過static標簽,django會去static目錄下尋找 -->
          </body>
          </html>
          

          {% static %}這個模板變量使用的就是STATIC_URL的值,例如默認的STATIC_URL值為/static/,那么上面模板變量引用后的值便為/static/開頭的地址。

          那么STATIC_URL又是怎么能正確的找到靜態文件地址的呢。

          1)在開發模式下(Debug=True)時,使用的是STATICFILES_DIRSapp下的static中的靜態文件,Django有默認的對STATIC_URL路由能自動找到放在里面的靜態文件。

          2)在部署模式(Debug=False)時,使用的是STATIC_ROOT中的靜態文件,此時則沒有了默認的對STATIC_URL的路由,需要自己在projecturls.py中寫一個,將STATIC_URL開頭的請求轉發到STATIC_ROOT中進行查找。

          from django.views.static import serve
          from django.conf.urls.static import static
          urlpatterns = [
              re_path(r'^static/(?P<path>.*)$', serve, {'document_root': settings.STATIC_ROOT}, name='static'),
          ]
          

          在部署生產環境時(Debug=False),通常使用另外一種方法就是使用Nginx來實現。

          如果你在項目中用到了static這個模板標簽,那一定要將nginx(或其他)服務器的/static配置到與STATIC_ROOT一致!(如果執行了收集的話)

          可以參考django部署配置:Centos7中使用Nginx+uWSGI+Django部署Web項目

          此時我們在應用中加載靜態文件的話就只需要這么來寫了,需要將STATIC_URL設為/static/,以img加載為例:

          <img src="/static/images/good.png" alt="My image"/>
          

          額外知識點:

          1、如果不想在模板文件中每次都通過{% load static %}加載靜態文件。

          TEMPLATES = [
              {
                  'BACKEND': 'django.template.backends.django.DjangoTemplates',
                  #'DIRS': [os.path.join(BASE_DIR, 'templates')]  # django2寫法
                   'DIRS': [BASE_DIR / 'templates'],  # django3寫法
                  ,
                  'APP_DIRS': True,
                  'OPTIONS': {
                      'context_processors': [
                          'django.template.context_processors.debug',
                          'django.template.context_processors.request',
                          'django.contrib.auth.context_processors.auth',
                          'django.contrib.messages.context_processors.messages',
                      ],
                      'builtins': ['django.templatetags.static']  # 添加這一行,就會將static當作內置的標簽,無需再手動load
                  },
              },
          ]
          

          備注:一般個人傾向于,直接將static文件放到項目根目錄下,下面再根據app名字進行分門別類。



          #Django#

          伙伴們大家好,本期想給大家分享一個模板,就是基于HTML+CSS+JS來模仿京東商城的前端界面。感興趣的小伙伴可以轉發該文,私信小編獲取代碼。

          先看一下主界面的展示效果圖,為gif動態圖,可點擊查看。

          主要技術點

          1、主界面采用平滑的輪播圖動態展示商品,左側采用側邊導航欄+多個浮動DIV展示商品具體信息,上方為導航欄,右側用浮動DIV完成公告欄的設計。

          2、除了正常看到的界面,在登陸和注冊界面中,使用juery完成數據的驗證和友好的樣式展示。

          3、此商城模板主要包括主界面、登陸界面、注冊界面、客戶問題反饋界面。

          主界面

          登陸界面

          注冊界面

          客戶反饋界面

          商品詳情界面

          最后上一下代碼圖,感興趣的小伙伴可以轉發+私信小編獲取代碼。同時歡迎持續關注小編相互交流。

          介紹:

          art-template 是一個簡約、超快的模板引擎。 它采用作用域預聲明的技術來優化模板渲染速度,從而獲得接近 JavaScript 極限的運行性能,并且同時支持 NodeJS 和瀏覽器。

          1.1 模板語法:

          art-template 同時支持兩種模板語法。標準語法可以讓模板更容易讀寫;原始語法具有強大的邏輯處理能力。

          標準語法

          {{if user}}
          <h2>{{user.name}}</h2>
          {{/if}}
          

          原始語法

          <% if (user) { %>
          <h2><%=user.name %></h2>
          <% } %>
          

          1.2 核心方法:

          // 基于模板名渲染模板
          template(filename, data);
          
          // 將模板源代碼編譯成函數
          template.compile(source, options);
          
          // 將模板源代碼編譯成函數并立即執行
          template.render(source, data, options);
          

          2 安裝

          2.1 安裝方法:

          • 通過npm安裝: npm install art-template --save
          • 下載安裝

          2.2 在瀏覽器中編譯

          因為瀏覽器不支持文件系統,所以 template(filename, data) 不支持傳入文件路徑,它內部使用 document.getElementById(filename).innerHTML 來獲取模板,例如:

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <meta http-equiv="X-UA-Compatible" content="ie=edge">
              <title>Document</title>
              <!-- 引入template-web.js -->
              <script src="./node_modules/art-template/lib/template-web.js"></script>
          </head>
          <body>
              <div id="container"></div>
              <!-- 創建 script 標簽創建模板,注意下面幾點 -->
              <!-- 1. type="text/該斜杠后可以是 html,template... 不是script即可)" -->
              <!-- 2. 給 script 標簽添加 id ,此 id 即為模板 id -->
              <!-- 3.模板 script 標簽必須在 template() 方法調用的 script 標簽之前 -->
              <script type="text/html" id="tpl">
                  {{if user}}
                  <h2>{{user.name}}</h2>
                  {{/if}}
              </script>
              <script>
                  var user={
                      name: 'Template username'
                  }
                  var html=template('tpl', {user: user})
                  var container=document.querySelector('#container');
                  container.innerHTML=html;
              </script>
          </body>
          </html>
          

          瀏覽器打開看到的結果如下:


          通過瀏覽器渲染模板.png

          3 語法

          art-template 支持標準語法與原始語法。標準語法可以讓模板易讀寫,而原始語法擁有強大的邏輯表達能力。

          標準語法支持基本模板語法以及基本 JavaScript 表達式;原始語法支持任意 JavaScript 語句,這和 EJS 一樣。

          3.1 輸出


          標準語法

          {{value}}
          {{data.key}}
          {{data['key']}}
          {{a ? b : c}}
          {{a || b}}
          {{a + b}}
          

          原始語法

          <%=value %>
          <%=data.key %>
          <%=data['key'] %>
          <%=a ? b : c %>
          <%=a || b %>
          <%=a + b %>
          

          3.2 原文輸出


          標準語法

          {{@ value}}
          

          原始語法

          <%- value %>
          

          3.3 條件輸出


          標準語法

          <!-- 單 if 判斷 -->
          {{if value}} 
          ... 
          {{/if}}
          
          <!-- if ... else ... 判斷 -->
          {{if v1}} 
          ... 
          {{else if v2}}
           ... 
          {{/if}}
          

          原始語法

          <!-- 單 if 判斷 -->
          <% if (value) { %>
          ...
          <% } %>
          
          <!-- if ... else ... 判斷 -->
          <% if (v1) { %>
          ...
          <% else if (v2) { %>
          ...
          <% } %>
          

          3.4 循環輸出


          標準語法

          {{each target}}
            {{$index}} {{$value}}
          {{/each}}
          

          target是一個數組,each用于對數組遍歷,$index 是數組的下標, $value是數組的值 原始語法

          <% for (var i=0; i < target.length; i++) { %>
          <%=i %> <%=target[i] %>
          <% } %>
          

          注意:

          1. target 支持 array 與object 的迭代,其默認值為 $data。
            具體看下面的例子:
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <meta http-equiv="X-UA-Compatible" content="ie=edge">
              <title>Document</title>
              <script src="./node_modules/art-template/lib/template-web.js"></script>
          </head>
          <body>
              <div id="container"></div>
              <script type="text/html" id="tpl">
                  <ul>
                      {{each user.arr}}
                      <li>
                          {{$index + 1}} ---- {{$value.type}} ---- {{$value.price}}
                          {{$data}}
                      </li>
                      {{/each}}
                  </ul>
              </script>
              <script>
                  var user={
                      obj: {
                          name: 'Bruce Lee',
                          age: 32,
                          gender: 'male'
                      },
                      arr: [
                          {type: 1, price: 10},
                          {type: 2, price: 12},
                          {type: 3, price: 18}
                      ] 
                  }
                  var html=template('tpl', {user: user})
                  var container=document.querySelector('#container');
                  container.innerHTML=html;
              </script>
          </body>
          </html>
          

          看輸出結果:


          each遍歷對象target(默認為$data).png

          圖中可以看出$data其實就是傳入模板的總數據對象(原始數據對象)

          1. $value 與 $index 可以自定義:{{each target val key}}。
            具體看下面例子:
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <meta http-equiv="X-UA-Compatible" content="ie=edge">
              <title>Document</title>
              <script src="./node_modules/art-template/lib/template-web.js"></script>
          </head>
          <body>
              <div id="container"></div>
              <script type="text/html" id="tpl">
                  <h4>each 遍歷數組,采用默認的索引 $index 和默認的值 $value</h4>
                  <ul>
                      <!-- each 遍歷數組,采用默認的索引 $index 和默認的值 $value -->
                      {{each user.arr}}
                      <li>
                          {{$index}} ---- {{$value}}
                      </li>
                      {{/each}}
                  </ul>
          
                  <h4>each 遍歷數組, 采用自定義的索引 b 和默認的值 a</h4>
                  <ul>
                      <!-- each 遍歷數組, 采用自定義的索引 b 和默認的值 a -->
                      {{each user.arr b a}}
                      <li>
                          {{a}} ---- {{b}}
                      </li>
                      {{/each}}
                  </ul>
          
                  <h4>each 遍歷對象, 采用默認的鍵 $index 和默認的值 $value</h4>
                  <ul>
                      <!-- each 遍歷對象, 采用默認的鍵 $index 和默認的值 $value  -->
                      {{each user.obj}}
                      <li>
                          {{$index}} ---- {{$value}}
                      </li>
                      {{/each}}
                  </ul>
          
                  <h4>each 遍歷對象,采用自定義的鍵 key 和自定義的值 val</h4>
                  <ul>
                      <!-- each 遍歷對象,采用自定義的鍵 key 和自定義的值 val -->
                      {{each user.obj val key}}
                      <li>
                          {{key}} ---- {{val}}
                      </li>
                      {{/each}}
                  </ul>
              </script>
              <script>
                  var user={
                      obj: {
                          name: 'Bruce Lee',
                          age: 32,
                          gender: 'male'
                      },
                      arr: [
                          { type: 1, price: 10 },
                          { type: 2, price: 12 },
                          { type: 3, price: 18 }
                      ]
                  }
                  var html=template('tpl', { user: user })
                  var container=document.querySelector('#container');
                  container.innerHTML=html;
              </script>
          </body>
          </html>
          

          看輸出結果:


          each遍歷數組和對象以及自定義$data和$index.png

          3.5 定義變量

          標準語法

          {{set temp=data.sub.content}}
          

          原始語法

          <% var temp=data.sub.content %>
          

          3.6 模板繼承

          標準語法

          {{extend './layout.html'}}
          {{block 'head'}}
          ...
          {{/block}}
          

          原始語法

          <% extend ('./layout.html') %>
          <% block('head', function () { %>
          ...
          <% }) %>
          

          模板繼承允許你構建一個包含站點共同元素的基本“模板骨架”,實例:

          <!--layout.art-->
          <!doctype html>
          <html>
          <head>
              <meta charset="utf-8">
              <title>{{block 'title'}}My Site{{/block}}</title>
          
              {{block 'head'}}
              <link rel="stylesheet" href="main.css">
              {{/block}}
          </head>
          <body>
              {{block 'content'}}{{/block}}
          </body>
          </html>
          
          <!--index.art-->
          {{extend './layout.art'}}
          
          {{block 'title'}}{{title}}{{/block}}
          
          {{block 'head'}}
              <link rel="stylesheet" href="custom.css">
          {{/block}}
          
          {{block 'content'}}
          <p>This is just an awesome page.</p>
          {{/block}}
          

          渲染 index.art 后,將自動應用布局骨架。

          3.7 子模板

          標準語法

          {{include './header.art'}}
          {{include './header.art' data}}
          

          原始語法

          <% include('./header.art') %>
          <% include('./header.art', data) %>
          

          看如下例子:

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <meta http-equiv="X-UA-Compatible" content="ie=edge">
              <title>art-template-filter</title>
              <!-- 引入 template-web.js -->
              <script src="./node_modules/art-template/lib/template-web.js"></script>
          </head>
          <body>
              <div class="container"></div>
              <script type="text/html" id="filterTpl">
                  <h3>{{date | format 'YYYy-mM-dd' | addQuotationMarks}}</h3>
                  <h3><%=$imports.addQuotationMarks($imports.format(date)) %></h3>
              </script>
              <script>
                  var data={
                      date: Date.now(),
                  }
                  // 定義日期格式化過濾器 format 方法:
                  template.defaults.imports.format=function (date, format) {
                      if (!format || format.toLowerCase()==='yyyy-mm-dd') {
                          var dt=new Date(date);
                          var y=dt.getFullYear();
                          var m=(dt.getMonth() + 1).toString().padStart(2, '0');
                          var d=dt.getDate().toString().padStart(2, '0');
                          return `${y}/${m}/$tzx3h9x`;
                      } else {
                          return 'invalid date';
                      }
                  }
                  // 定義給字符串加引號過濾器 addQuotationMarks 方法:
                  template.defaults.imports.addQuotationMarks=function (str) {
                      return `"${str}"`;
                  }
                  // 調用 template 方法,渲染模板和數據
                  var html=template('filterTpl', data);
                  document.querySelector('.container').innerHTML=html;
              </script>
          </body>
          </html>
          

          注意:

          • {{date | format 'YYYy-mM-dd' | addQuotationMarks}}
            date 默認為 format 過濾器(方法)的第一個參數, 'YYYy-mM-dd' 才是format 過濾器的第二個參數,date 經過 format 過濾器過濾后,得到的結果,又作為
            addQuotationMarks 過濾器的默認參數,如果有更多的過濾器,那么就把前一層過濾器過濾的結果,作為下一個過濾器的參數一層層過濾下去

          4 調試

          template.defaults.debug art-template 內建調試器,能夠捕獲到語法與運行錯誤,并且支持自定義的語法。在 NodeJS 中調試模式會根據環境變量自動開啟:process.env.NODE_ENV !=='production' 設置 template.defaults.debug=true 后,等同于:

          {
              "cache": false,
              "minimize": false,
              "compileDebug": true
          }
          

          5 模板變量

          template.defaults.imports 模板通過 $imports 可以訪問到模板外部的全局變量和導入的變量。

          5.1 導入變量

          template.defaults.imports.log=console.log;
          
          <% $imports.log('Hello, template.defaults.imports.log') %>
          

          看下面例子:

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <meta http-equiv="X-UA-Compatible" content="ie=edge">
              <title>template.defaults.imports</title>
              <script src="./node_modules/art-template/lib/template-web.js"></script>
          </head>
          <body>
              <div class="container">
              </div>
              <script type="text/html" id="importsTpl">
                  <% $imports.log('Hello, template.defaults.imports.log') %>
                  <%=$imports.date %>
              </script>
              <script>
                  var data={};
                  template.defaults.imports.log=console.log;
                  template.defaults.imports.date=new Date();
                  template.defaults.debug=true;
                  var html=template('importsTpl', data);
                  document.querySelector('.container').innerHTML=html;
              </script>
          </body>
          </html>
          

          注意:

          這些語法必須寫在模板中,在模板中才會起作用;

          5.2 內置變量清單

          • $data 傳入模板的數據;
          • $imports 外部導入的變量以及全局變量;
          • print 字符串輸出函數;
          • include 子模板載入函數
          • extend 模板繼承模板導入函數
          • block 模板塊生命函數

          最后,小編想說:我是一名python開發工程師,

          整理了一套最新的python系統學習教程,

          想要這些資料的可以關注私信小編“01”即可(免費分享哦)希望能對你有所幫助


          主站蜘蛛池模板: 极品尤物一区二区三区| 波多野结衣在线观看一区二区三区| 在线免费观看一区二区三区| 久久精品国产一区二区三区日韩| 中文字幕AV一区二区三区人妻少妇| 韩日午夜在线资源一区二区| 国内精品视频一区二区三区八戒| 日韩亚洲一区二区三区| 精品国产一区二区三区香蕉事| 亚洲一区二区三区免费观看| 无码人妻久久一区二区三区免费| 天码av无码一区二区三区四区| 丝袜美腿一区二区三区| 日韩中文字幕精品免费一区| 精品国产一区二区三区麻豆| 亚洲日本va午夜中文字幕一区| 国产剧情国产精品一区| 国产凹凸在线一区二区| 真实国产乱子伦精品一区二区三区 | 日韩少妇无码一区二区三区| 日本无码一区二区三区白峰美| 97精品一区二区视频在线观看| 亚洲午夜一区二区电影院| 亚洲一区二区三区电影| 亚洲综合无码一区二区三区| 精品日韩亚洲AV无码一区二区三区 | 国产精品亚洲一区二区三区久久| 亚州AV综合色区无码一区| 亚洲另类无码一区二区三区| 精品无码国产一区二区三区麻豆| 国产日韩综合一区二区性色AV| 国产品无码一区二区三区在线| 在线不卡一区二区三区日韩| 一区二区三区视频网站| 少妇人妻偷人精品一区二区| 亚洲狠狠久久综合一区77777| 亚洲一区二区三区在线 | 偷拍精品视频一区二区三区| 久久99精品免费一区二区| 亚洲国产成人一区二区精品区| 亚洲国产一区国产亚洲|