第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

Django 入門教程

課程導(dǎo)學(xué)
Django 慕課教程使用指南
Django開發(fā)實戰(zhàn)
35 開發(fā)實戰(zhàn)

DTL 常用過濾器使用

Django 2.2 中提供了 60 多個內(nèi)置的過濾器,已經(jīng)能滿足我們的大部分場景。如果沒有適合我們業(yè)務(wù)場景的,還可以自定義過濾器。Django 的官方文檔是做的非常齊全的,我們可以從官網(wǎng)上找到任何一個過濾器的說明和使用示例。在這里會介紹部分常用的過濾器,同時可能結(jié)合源碼探究過濾器內(nèi)部實現(xiàn)原理。

1. 常用過濾器

1.1 add

將傳過來的參數(shù)加上某個值。示例:

{{ value|add:"2" }}

假設(shè)我們傳過來的值4,那么翻譯的結(jié)果將會變成6。那么如果 add 的參數(shù)是一個字符串呢,輸出結(jié)果是怎么樣的?我們來看下這個過濾器實現(xiàn)的代碼就能知道結(jié)果了:

@register.filter(is_safe=False)
def add(value, arg):
    """Add the arg to the value."""
    try:
        return int(value) + int(arg)
    except (ValueError, TypeError):
        try:
            return value + arg
        except Exception:
            return ''

如果value 和 add 的參數(shù)值都是數(shù)字, 那么轉(zhuǎn)換的結(jié)果就是兩個數(shù)字之和;如果一個是字母字符串,另一個參數(shù)值是數(shù)字字符串,那么返回的是空字符串;如果兩個都是字母字符串,那么會執(zhí)行字符串相加。

1.2 capfirst

將 value 值得第一個字符大寫。如果第一字符非字母形式,那么這個過濾器不會起作用。示例如下:

{{ value|capfirst }}

例如 value 值為 “imooc”,那么過濾器輸出的結(jié)果為 “Imooc”。該過濾器的實現(xiàn)代碼如下:

@register.filter(is_safe=True)
@stringfilter
def capfirst(value):
    """Capitalize the first character of the value."""
    return value and value[0].upper() + value[1:]

1.3 center

將輸入的字符按照給定寬度居中。示例如下:

{{ value|center:"15" }}

假設(shè)輸入的 value 值為 “imooc”,那么輸出的字符串為" imooc "。來繼續(xù)查看該過濾器實現(xiàn)代碼:

@register.filter(is_safe=True)
@stringfilter
def center(value, arg):
    """Center the value in a field of a given width."""
    return value.center(int(arg))

這個過濾器實現(xiàn)也非常簡單,直接使用字符串的 center() 方法,將字符串的總寬度傳入即可自動將字符串居中。

1.4 cut

移除 value 中所有指定字符。示例如下:

{{ value|cut:" " }}

假設(shè)輸入的字符串為:‘hello world, game over’,那么經(jīng)過此過濾器后,得到的結(jié)果為:‘helloworld,gameover’

@register.filter
@stringfilter
def cut(value, arg):
    """Remove all values of arg from the given string."""
    safe = isinstance(value, SafeData)
    value = value.replace(arg, '')
    if safe and arg != ';':
        return mark_safe(value)
    return value

可以看到這里其實使用的就是 python 中字符串的 replace() 方法進行移除指定字符的。

1.4 date

對輸入的時間字符串按照指定格式輸出。示例如下:

{{ value|date:"D d M Y" }}

這里參數(shù)含義較多,請參考官方文檔。

1.5 default

如果 value 值可認(rèn)為是 False (比如空字符串,空字典、空數(shù)組等),則使用給定的默認(rèn)值,否則使用 value 的值。示例如下:

{{ value|default:"nothing" }}

和這個過濾器比較相近的一個叫做:default_if_none,它是只在 value 值為 None 時,才會輸出默認(rèn)值,否則依舊使用 value 的值:

(django-manual) [root@server first_django_app]# cat templates/test_filter.html 
{{ empty|default:"nothing" }}
{{ empty_if_none|default_if_none:"none" }}

(django-manual) [root@server first_django_app]# python manage.py shell
Python 3.8.1 (default, Dec 24 2019, 17:04:00) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.template.loader import get_template
>>> tp = get_template('test_filter.html')
>>> print(tp.render(context={'empty':{}, 'empty_if_none':{}}))
nothing
{}

>>> print(tp.render(context={'empty':[], 'empty_if_none':[]}))
nothing
[]

>>> print(tp.render(context={'empty':'', 'empty_if_none':''}))
nothing


>>> print(tp.render(context={'empty':None, 'empty_if_none':None}))
nothing
none

1.6 dictsort

獲取字典列表,并按參數(shù)中給定的 key 值對列表進行排序。示例如下:

{{ value|dictsort:"name" }}

假設(shè)我們輸入的 value 值為:

[
    {'name': 'zed', 'age': 19},
    {'name': 'amy', 'age': 22},
    {'name': 'joe', 'age': 31},
]

此時輸出的結(jié)果為:

[
    {'name': 'amy', 'age': 22},
    {'name': 'joe', 'age': 31},
    {'name': 'zed', 'age': 19},
]

另外一種復(fù)雜的寫法如下:

{% for book in books|dictsort:"author.age" %}
    * {{ book.title }} ({{ book.author.name }})
{% endfor %}

如果 value 的值為:

[
    {'title': '1984', 'author': {'name': 'George', 'age': 45}},
    {'title': 'Timequake', 'author': {'name': 'Kurt', 'age': 75}},
    {'title': 'Alice', 'author': {'name': 'Lewis', 'age': 33}},
]

此時的輸出為:

* Alice (Lewis)
* 1984 (George)
* Timequake (Kurt)

上面的排序是按照從小到大的順序執(zhí)行的,如果想要輸出按照從大到小的順序,可以使用 dictsortreversed 過濾器指令。

1.7 divisibleby

如果輸入 value 值可被參數(shù)整除,則輸出 True。用法如下:

{{ value|divisibleby:"3" }}

如果輸入值為 “21”,則輸出為 True。該指令實現(xiàn)的代碼如下,非常簡單。

@register.filter(is_safe=False)
def divisibleby(value, arg):
    """Return True if the value is divisible by the argument."""
    return int(value) % int(arg) == 0

1.8 escape

控制 HTML 轉(zhuǎn)義,替換 value 中的某些 HTML 特殊字符。

  • < is converted to &lt;
  • > is converted to &gt;
  • ' (single quote) is converted to &#39;
  • " (double quote) is converted to &quto;
  • & is converted to &amp;
{% autoescape off %}
    {{ title|escape }}
{% endautoescape %}

1.9 filesizeformat

將輸入值轉(zhuǎn)換成易讀模式,特別是針對文件大小,如 ‘13 KB’、‘2.4 MB’ 等。示例:

{{ value|filesizeformat }}

假設(shè)輸入的 value 值為 123456789,輸出結(jié)果為 “117.7 MB”。其實現(xiàn)代碼如下:

@register.filter(is_safe=True)
def filesizeformat(bytes_):
    """
    Format the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB,
    102 bytes, etc.).
    """
    try:
        bytes_ = float(bytes_)
    except (TypeError, ValueError, UnicodeDecodeError):
        value = ngettext("%(size)d byte", "%(size)d bytes", 0) % {'size': 0}
        return avoid_wrapping(value)

    def filesize_number_format(value):
        return formats.number_format(round(value, 1), 1)

    KB = 1 << 10
    MB = 1 << 20
    GB = 1 << 30
    TB = 1 << 40
    PB = 1 << 50

    # 如果是負數(shù),需要轉(zhuǎn)成正數(shù)然后轉(zhuǎn)換
    negative = bytes_ < 0
    if negative:
        bytes_ = -bytes_  # Allow formatting of negative numbers.
    # 
    if bytes_ < KB:
        value = ngettext("%(size)d byte", "%(size)d bytes", bytes_) % {'size': bytes_}
    elif bytes_ < MB:
        value = gettext("%s KB") % filesize_number_format(bytes_ / KB)
    elif bytes_ < GB:
        value = gettext("%s MB") % filesize_number_format(bytes_ / MB)
    elif bytes_ < TB:
        value = gettext("%s GB") % filesize_number_format(bytes_ / GB)
    elif bytes_ < PB:
        value = gettext("%s TB") % filesize_number_format(bytes_ / TB)
    else:
        value = gettext("%s PB") % filesize_number_format(bytes_ / PB)

    # 如果是負數(shù),轉(zhuǎn)換后再加上-號
    if negative:
        value = "-%s" % value
    # 去掉'\0xa0'字符    
    return avoid_wrapping(value)

1.10 first

該過濾器會返回輸入列表中的第一項。示例如下:

{{ value|first }}

如果是輸入的是列表 [‘a(chǎn)’, ‘b’, ‘c’],那么輸出的為 ‘a(chǎn)’。和 first 指令相反作用的過濾器為 last,對于本次輸出的結(jié)果為 ‘c’。first 和 last 過濾器的實現(xiàn)代碼如下,非常簡單:

@register.filter(is_safe=False)
def first(value):
    """Return the first item in a list."""
    try:
        return value[0]
    except IndexError:
        return ''
    
@register.filter(is_safe=True)
def last(value):
    """Return the last item in a list."""
    try:
        return value[-1]
    except IndexError:
        return ''

1.11 join

使用指定字符串連接輸出的列表或者字符串,就像 python 中字符串的 join() 方法。示例用法如下:

{{ value|join:" // " }}

假設(shè)輸入的值為['a', 'b', 'c'],那么輸出為 “a // b // c”。它的實現(xiàn)代碼如下:

@register.filter(is_safe=True, needs_autoescape=True)
def join(value, arg, autoescape=True):
    """Join a list with a string, like Python's ``str.join(list)``."""
    try:
        if autoescape:
            value = [conditional_escape(v) for v in value]
        # 最核心的處理是使用字符串的join()方法
        data = conditional_escape(arg).join(value)
    except TypeError:  # Fail silently if arg isn't iterable.
        return value
    return mark_safe(data)

1.12 length

返回輸入值的長度,輸入的可以是字符串和列表。示例如下:

{{ value|length }}

如果 value 的值為:[‘a(chǎn)’, ‘b’, ‘c’, ‘d’] 或者 ‘a(chǎn)bcd’,輸出都是4。對于未定義的變量值,輸出為0。它的實現(xiàn)代碼也是非常簡單,如下:

@register.filter(is_safe=False)
def length(value):
    """Return the length of the value - useful for lists."""
    try:
        return len(value)
    except (ValueError, TypeError):
        return 0

1.14 floatformat

對數(shù)據(jù)進行四舍五入處理,參數(shù)是保留小數(shù)位數(shù),可以為正負。若無參數(shù) arg, 默認(rèn)保留1位小數(shù)。

用法示例1:不帶參數(shù)

Value Template Output
34.23234 {{ value|floatformat }} 34.2
34.00000 {{ value|floatformat }} 34
34.26000 {{ value|floatformat }} 34.3

示例用法2:帶上正參數(shù),保留有效參數(shù)位

Value Template Output
34.23234 {{ value|floatformat:3 }} 34.232
34.00000 {{ value|floatformat:3 }} 34.000
34.26000 {{ value|floatformat:3 }} 34.260

示例用法3:帶上0參數(shù),即四舍五入取整輸出

Value Template Output
34.23234 {{ value|floatformat:“0” }} 34
34.00000 {{ value|floatformat:“0” }} 34
39.56000 {{ value|floatformat:“0” }} 40

示例用法3:帶上負參數(shù),對于沒有小數(shù)顯示的則會默認(rèn)取整。

Value Template Output
34.23234 {{ value|floatformat:"-3" }} 34.232
34.00000 {{ value|floatformat:"-3" }} 34
34.26000 {{ value|floatformat:"-3" }} 24.269

1.15 linenumbers

給輸如的文本加上行號。用法示例:

{{ value|linenumbers }}

假設(shè)輸入的文本為:

one
two
three

那么輸出為:

1. one
2. two
3. three

查看 Django 內(nèi)部源碼,可以看到 linenumbers 過濾器實現(xiàn)的代碼:

@register.filter(is_safe=True, needs_autoescape=True)
@stringfilter
def linenumbers(value, autoescape=True):
    """Display text with line numbers."""
    lines = value.split('\n')
    # Find the maximum width of the line count, for use with zero padding
    # string format command
    width = str(len(str(len(lines))))
    if not autoescape or isinstance(value, SafeData):
        for i, line in enumerate(lines):
            lines[i] = ("%0" + width + "d. %s") % (i + 1, line)
    else:
        for i, line in enumerate(lines):
            lines[i] = ("%0" + width + "d. %s") % (i + 1, escape(line))
    return mark_safe('\n'.join(lines))

可以看到,其實 linenumbers 就是在每行文本的前面加上了一個從1開始的編號。

注意:代碼中的 width 含義是確定最長行號所占的字符寬度。比如編號1000,占據(jù)4個字符長度,后面所有行程的行統(tǒng)一需要加上4個字符長度用于顯示行號。

1.16 ljust/rjust

ljust/rjust 分別表示以左對齊或者右對齊方式輸出 value 值。用法如下:

{{ value|ljsut:"10"}}
{{ vlaue|rjust:"10"}}

假設(shè)輸入的 value 值為 “imooc”,第一個輸出為 "imooc “,第二個輸出為 " imooc”。其過濾器實現(xiàn)代碼分別如下:

@register.filter(is_safe=True)
@stringfilter
def ljust(value, arg):
    """Left-align the value in a field of a given width."""
    return value.ljust(int(arg))

@register.filter(is_safe=True)
@stringfilter
def rjust(value, arg):
    """Right-align the value in a field of a given width."""
    return value.rjust(int(arg))

1.17 lower/upper

lower/upper 過濾器表示對輸入的字符串全部轉(zhuǎn)成大/小寫。用法如下:

{{ value|lower }}
{{ value|upper }}

假設(shè) value 值為 “Hello, World!”,那么第一個輸出為 “hello, world!”, 第二個輸出為 “HELLO, WORLD!”。

1.18 make_list

將輸入的 value 值轉(zhuǎn)成列表形式。如果輸入的是字符串,則轉(zhuǎn)成字符列表。如果輸入的是整數(shù),會首先轉(zhuǎn)成字符串形式,然后在轉(zhuǎn)成列表。用法如下:

{{ value|make_list }}

假設(shè)輸入的 value 值為 “imooc”,輸出結(jié)果為 [‘i’, ‘m’, ‘o’, ‘o’, ‘c’]。如果輸入的是 123,那么輸出為 [‘1’, ‘2’, ‘3’]。它的實現(xiàn)過程非常簡單,對輸入的文本直接使用 list() 方法并返回。

@register.filter(is_safe=False)
@stringfilter
def make_list(value):
    """
    Return the value turned into a list.

    For an integer, it's a list of digits.
    For a string, it's a list of characters.
    """
    return list(value)

1.19 random

對于輸入的列表,從中任選一個元素返回。用法如下:

{{ value|random }}

1.20 slice

類似于 python 列表的 slice() 方法。示例如下:

{# 相當(dāng)于some_list[:2] #}
{{ some_list|slice:":2" }}

假設(shè)輸入列表 [‘a(chǎn)’, ‘b’, ‘c’],那么上述結(jié)果輸出 [‘a(chǎn)’, ‘b’]。

1.21 title

對輸入字符串中每個單詞的首字母大寫。用法如下:

{{ value|title }}

假設(shè) value 值為 “my FIRST post”, 輸出 “My First Post”

1.22 truncatechars

對輸入的字符串進行截取,參數(shù) arg 含義是保留字符串長度。如果字符串長度超出了保留長度,那么會保留 int(arg) -1 個字符并加上 ‘…’,一共是 int(arg) 個字符。示例如下:

{{ value|truncatechars:7 }}

假設(shè) value 的值為 “Joel is a slug”,上述過濾結(jié)果為 “Joel i…”。

1.23 truncatewords

截取固定單詞數(shù)的字符串。參數(shù) arg 的含義是保留單詞書。示例如下:

{{ value|truncatewords }}

假設(shè) value 的值為 “Joel is a slug”,那么上述過濾結(jié)果為 “Joel is …”。

1.24 urlencode

對 URL 中的特殊字符進行轉(zhuǎn)義。示例如下:

{{ value|urlencode }}

假設(shè) value 值 為 https://www.example.org/foo?a=b&c=d", 上述過濾結(jié)果為: "https%3A//www.example.org/foo%3Fa%3Db%26c%3Dd"。

1.25 wordcount

返回字符串中單詞個數(shù)。示例如下:

{{ value|wordcount }}

假設(shè) value 的值為 “Joel is a slug”,那么上述過濾結(jié)果為4。

1.26 wordwrap

對于輸入的文本以指定長度換行。示例如下:

{{ value|wordwrap:5 }}

假設(shè) value 的值為 “Joel is a slug”,那么上述過濾結(jié)果為:

Joel
is a
slug

至此,比較常見的過濾器就算介紹完了,更多過濾器及其詳細用法可以參考官方文檔以及相應(yīng)的源代碼。

2. 小結(jié)

本小節(jié)我們介紹了 Django 中的常用過濾器,并給出了部分過濾器的實現(xiàn)代碼。接下來,我們將學(xué)習(xí)在 Django 中如何實現(xiàn)自定義標(biāo)簽和過濾器并使用。