欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Django自定義模板過濾器和標(biāo)簽的實現(xiàn)方法

 更新時間:2019年08月21日 09:58:29   作者:杜賽  
這篇文章主要介紹了Django自定義模板過濾器和標(biāo)簽的實現(xiàn)方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下

現(xiàn)在我們已經(jīng)很熟悉Django的MTV模式了。模板(template)負(fù)責(zé)如何去展示數(shù)據(jù),而視圖(view)負(fù)責(zé)篩選出正確的數(shù)據(jù)。因此通常來說邏輯都是放到視圖中的,但模板也需要一些 和表示相關(guān)的邏輯 :比如循環(huán)展示(如 {% for ... %} )、或者以某種特定格式輸出(如 {{ ...|date:'Y-m-d' }} )等,這些功能都是靠模板的 過濾器(filters) 和 標(biāo)簽(tags) 實現(xiàn)的。

Django的模板語言包含了很多內(nèi)置的過濾器和標(biāo)簽,設(shè)計目的是滿足應(yīng)用需要占位邏輯需求。但有的時候這些通用的功能滿足不了你的某些需求,這時候就需要自定義過濾器和標(biāo)簽來實現(xiàn)了。

前置條件

要在Django中使用模板過濾器或標(biāo)簽,就首先得 注冊 它們。

注冊方法如下:

  • 在APP中新建名為 templatetags 的目錄(方便起見,教程選擇了 article 這個APP)
  • 在此目錄中新建名為 __init__.py 的空文件,使得此目錄被視作一個Python的包
  • 在此目錄中新建python文件(比如 my_filters_and_tags.py ),就可以在里面愉快的寫代碼啦

完成后的目錄結(jié)構(gòu)如下:

article/
  __init__.py
  views.py
  models.py
  # 新增目錄
  templatetags/
    __init__.py # 空文件
    my_filters_and_tags.py # 即將寫代碼的地方
  ...

請注意:

  • 目錄必須位于已注冊的APP中,這是出于安全性的考慮
  • 新建目錄后,必須手動重啟服務(wù)器,里面的過濾器和標(biāo)簽才能生效

前置條件就完成了,接下來我們看看如何寫一個模板過濾器。

模板過濾器

過濾器 filter 的表現(xiàn)形式為緊跟在上下文后面的管道符 | ,管道符后面是filter的名稱: {{ ...|filter_name }} 。有的filter還可以帶有參數(shù): {{ ...|filter_name:var }} 。

注意過濾器名稱的冒號后面不能有空格。

filter 這個名字可能會讓你誤認(rèn)為它只是用來篩選某些特定數(shù)據(jù)的,但實際上它遠(yuǎn)不止這點功能。它可以改變上下文的最終展示效果,也可以將上下文通過運算輸出為特定的值。

小試牛刀

要成為一個可用的 filter ,文件中必須包含一個名為 register 的模塊級變量,它是一個 template.Library 實例,所有的 filters 均在其中注冊。所以在 my_filter_and_tags.py 文件中輸入以下內(nèi)容:

article/templatetags/my_filter_and_tags.py

from django import template
register = template.Library()

接下來就可以像寫普通的Python函數(shù)一樣寫過濾器了:

article/templatetags/my_filter_and_tags.py
from django import template
register = template.Library()
@register.filter(name='transfer')
def transfer(value, arg):
  """將輸出強制轉(zhuǎn)換為字符串 arg """
  return arg
@register.filter()
def lower(value):
  """將字符串轉(zhuǎn)換為小寫字符"""
  return value.lower()

filter可以通過裝飾器進(jìn)行注冊。若注冊裝飾器中攜帶了 name 參數(shù),則其值為此filter的名稱;若未攜帶,則函數(shù)名就是filter的名稱。

filter必須是有一到兩個參數(shù)的Python函數(shù)。第一個參數(shù)是上下文本身,第二個參數(shù)則由filter提供。舉個栗子,在過濾器 {{ var|foo:"bar" }} 中,變量 var 為第一個參數(shù),變量 bar 則作為第二個參數(shù)。

調(diào)用這些filter的方法是在模板文件中用 {% load ... %} 將filter文件的名稱加載進(jìn)去,像這樣:

# 任意模板文件中
{% load my_filters_and_tags %}
{{ 'ABC'|transfer:'cool' }} # 輸出:'cool'
{{ 'ABC'|lower }} # 輸出: 'abc'

更人性化的時間

了解完filter的使用方法后,下面來寫點更實用的功能。

對人類這種生物來說, 相對時間 通常比 絕對時間 要更容易閱讀。 發(fā)表于 3天前 可以輕易得知此文章剛發(fā)表不久;而 發(fā)表于 2019年8月10日 你還得想想今天到底幾號來著。

因此寫一個顯示相對日期的 time_since_zh 過濾器:

article/templatetags/my_filter_and_tags.py
...
from django.utils import timezone
import math
# 獲取相對時間
@register.filter(name='timesince_zh')
def time_since_zh(value):
  now = timezone.now()
  diff = now - value
  if diff.days == 0 and diff.seconds >= 0 and diff.seconds < 60:
    return '剛剛'
  if diff.days == 0 and diff.seconds >= 60 and diff.seconds < 3600:
    return str(math.floor(diff.seconds / 60)) + "分鐘前"
  if diff.days == 0 and diff.seconds >= 3600 and diff.seconds < 86400:
    return str(math.floor(diff.seconds / 3600)) + "小時前"
  if diff.days >= 1 and diff.days < 30:
    return str(diff.days) + "天前"
  if diff.days >= 30 and diff.days < 365:
    return str(math.floor(diff.days / 30)) + "個月前"
  if diff.days >= 365:
    return str(math.floor(diff.days / 365)) + "年前"

代碼功能很簡單,就是將文章發(fā)布時間和當(dāng)前時間作比較,然后返回適當(dāng)?shù)淖址?/p>

修改文章列表模板文件中與發(fā)布時間相關(guān)的代碼,把剛寫的filter用上:

templates/article/list.html
...
{% load my_filters_and_tags %}
...
<!-- 舊代碼
{{ article.created|date:'Y-m-d' }}
-->
<!-- 新代碼 -->
{{ article.created|timesince_zh }}
...

效果如下:

 

實際上Django內(nèi)置了一個 timesince 過濾器,只不過顯示日期是英文的,不夠友好。

模板標(biāo)簽

模板標(biāo)簽(tag)比過濾器更復(fù)雜,功能也更強大。

標(biāo)簽 tag 的表現(xiàn)形式為 {% tag_name ... %} ,比如我們非常熟悉的內(nèi)置標(biāo)簽 {% url ... %} 、 {% static ... %} 等。如果內(nèi)置標(biāo)簽滿足不了你的需求,Django 提供了很多快捷方式,簡化了編寫絕大多數(shù)類型的標(biāo)簽過程。

簡單標(biāo)簽

simple_tag 就是最重要的標(biāo)簽類型。標(biāo)簽的注冊方法跟過濾器非常類似:

@register.simple_tag
def change_http_to_https(url):
  new_url = url.replace('http://', 'https://')
  return new_url

調(diào)用時同樣記得在模板文件中用 {% load... %} 引入。用法你應(yīng)該猜得到: {% change_http_to_https ... %} ,這個標(biāo)簽的作用是將http鏈接替換為https鏈接。

用 Django-allauth 進(jìn)行微博登錄,默認(rèn)返回的用戶頭像是 http 鏈接(雖然微博有 https 版本的頭像)。如果你的站點已經(jīng)升級為 https 了,又不想花時間去研究微博的接口,那么這個標(biāo)簽就可以派上用場了。
順帶一說, Django-allauth 第三方登錄的頭像 url 保存在 User.socialaccount_set.all.0.get_avatar_url 中。

下面這個例子可以返回指定格式的時間字符串:

import datetime

@register.simple_tag
def current_time(format_string):
  return datetime.datetime.now().strftime(format_string)

調(diào)用時你可以將其保存為模板變量,以便你在期望的位置多次調(diào)用:

{% current_time "%Y-%m-%d %I:%M %p" as the_time %}
<p>The time is {{ the_time }}.</p>
<p>Again, the time is {{ the_time }}.</p>

模板標(biāo)簽也可以訪問當(dāng)前的上下文,只需要在注冊標(biāo)簽時傳入 takes_context 參數(shù):

@register.simple_tag(takes_context=True)
def current_time(context, format_string):
  timezone = context['timezone']
  return your_get_current_time_method(timezone, format_string)

注意,第一個參數(shù)必須是 context 。

與過濾器不同的是,標(biāo)簽可以接受任意數(shù)量的位置或關(guān)鍵字參數(shù)。例如:

@register.simple_tag
def my_tag(a, b, *args, **kwargs):
  warning = kwargs['warning']
  profile = kwargs['profile']
  ...
  return ...

在模板中調(diào)用時,任意數(shù)量的、以空格分隔的參數(shù)會被傳遞給模板標(biāo)簽。與 Python 中類似,關(guān)鍵字參數(shù)的賦值使用等號(" = "),且必須在位置參數(shù)后提供:

{% my_tag 123 "abcd" book.title warning=message profile=user.profile %}

包含標(biāo)簽

包含標(biāo)簽可以讓另一個模板為當(dāng)前模板渲染數(shù)據(jù)。聽起來比較拗口,還是通過例子來理解。

假設(shè)現(xiàn)在有一個需求,是要在文章詳情頁面中,顯示所有相關(guān)評論的發(fā)布時間。因此在 my_filter_and_tags.py 中寫入:

my_filter_and_tags.py

...

@register.inclusion_tag('article/tag_list.html')
def show_comments_pub_time(article):
  """顯示文章評論的發(fā)布時間"""
  comments = article.comments.all()
  return {'comments': comments}

函數(shù)傳入的參數(shù)可以是模板中的上下文變量。函數(shù)體內(nèi)部取得了所有相關(guān)評論的查詢集,然后把結(jié)果 comments 返回。注意返回結(jié)果是進(jìn)入到 tag_list.html 這個模板中去了,因此新建它并寫入:

templates/article/tag_list.html

<ul>
{% for comment in comments %}
  <li> {{ comment.created }} </li>
{% endfor %}
</ul>

然后在文章詳情頁面的模板中,隨便找一個位置寫入:

templates/article/detail.html
...
{% load my_filters_and_tags %}
...
{% show_comments_pub_time article %}

刷新詳情頁面,順利的話就能看到所有評論的發(fā)表時間都展示出來了。

包含標(biāo)簽的另一個應(yīng)用場景就是各種按鈕了。有的按鈕看上去長得都差不多,但是根據(jù)頁面不同會有不同的功能,這時候也可以用包含標(biāo)簽來實現(xiàn)。

總之,包含標(biāo)簽可以將常用的模板代碼打包成小組件,方便重復(fù)利用。

目前的博客項目中暫時還用不到包含標(biāo)簽,所以放心的刪除上面的代碼吧。

總結(jié)

以上所述是小編給大家介紹的Django自定義模板過濾器和標(biāo)簽的實現(xiàn)方法,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復(fù)大家的!

相關(guān)文章

  • python自動化測試之異常及日志操作實例分析

    python自動化測試之異常及日志操作實例分析

    這篇文章主要介紹了python自動化測試之異常及日志操作,結(jié)合實例形式分析了python自動化測試中的異常捕獲與日志記錄相關(guān)操作技巧,需要的朋友可以參考下
    2019-11-11
  • django 實現(xiàn)手動存儲文件到model的FileField

    django 實現(xiàn)手動存儲文件到model的FileField

    這篇文章主要介紹了django 實現(xiàn)手動存儲文件到model的FileField,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • 常用python爬蟲庫介紹與簡要說明

    常用python爬蟲庫介紹與簡要說明

    本文介紹了一些常用的python爬蟲庫其中包括python網(wǎng)絡(luò)庫,python網(wǎng)絡(luò)爬蟲框架,python HTML解析,python文本處理,python 自然語言處理,python 瀏覽器模擬等各種常用的python庫
    2020-01-01
  • python在Windows下安裝setuptools(easy_install工具)步驟詳解

    python在Windows下安裝setuptools(easy_install工具)步驟詳解

    這篇文章主要介紹了python在Windows下安裝setuptools(easy_install工具)步驟,簡單介紹了setuptools并分析了其安裝步驟與所涉及的相關(guān)軟件,需要的朋友可以參考下
    2016-07-07
  • python實現(xiàn)的發(fā)郵件功能示例

    python實現(xiàn)的發(fā)郵件功能示例

    這篇文章主要介紹了python實現(xiàn)的發(fā)郵件功能,結(jié)合實例形式分析了Python使用網(wǎng)易郵箱發(fā)送郵件的相關(guān)操作技巧,需要的朋友可以參考下
    2019-09-09
  • Python中如何引入第三方模塊

    Python中如何引入第三方模塊

    在本篇文章中小編給大家分享的是一篇關(guān)于Python中如何引入第三方模塊的相關(guān)知識點,需要的朋友們可以學(xué)習(xí)下。
    2020-05-05
  • 帶你認(rèn)識Django

    帶你認(rèn)識Django

    今天小編就為大家分享一篇關(guān)于帶你認(rèn)識Django,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 利用python模擬sql語句對員工表格進(jìn)行增刪改查

    利用python模擬sql語句對員工表格進(jìn)行增刪改查

    這篇文章主要給大家介紹了關(guān)于利用python模擬sql語句實現(xiàn)對員工表格進(jìn)行增刪改查的相關(guān)資料,文中介紹了詳細(xì)的需求以及示例代碼,對大家的理解和學(xué)習(xí)具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-07-07
  • Python 專題六 局部變量、全局變量global、導(dǎo)入模塊變量

    Python 專題六 局部變量、全局變量global、導(dǎo)入模塊變量

    本文主要講述python全局變量、局部變量和導(dǎo)入模塊變量的方法。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-03-03
  • python中的classmethod與staticmethod

    python中的classmethod與staticmethod

    這篇文章主要介紹了python中的classmethod與staticmethod,
    2022-01-01

最新評論