[英]Comma separated lists in django templates
如果fruits
是列表['apples', 'oranges', 'pears']
,
有沒有一種使用django模板標簽生成“蘋果,橘子和梨”的快捷方式?
我知道使用循環和{% if counter.last %}
語句來做這個並不困難,但因為我將反復使用這個,我想我將不得不學習如何編寫自定義 標簽 過濾器,如果它已經完成,我不想重新發明輪子。
作為延伸,我試圖放棄牛津逗號 (即返回“蘋果,橘子和梨”)甚至更加混亂。
第一選擇:使用現有的連接模板標記。
http://docs.djangoproject.com/en/dev/ref/templates/builtins/#join
這是他們的例子
{{ value|join:" // " }}
第二選擇:在視圖中執行。
fruits_text = ", ".join( fruits )
將fruits_text
提供給模板進行渲染。
這是一個超級簡單的解決方案。 將此代碼放入comma.html:
{% if not forloop.last %}{% ifequal forloop.revcounter 2 %} and {% else %}, {% endifequal %}{% else %}{% endif %}
現在無論你把逗號放在哪里,都要包含“comma.html”:
{% for cat in cats %}
Kitty {{cat.name}}{% include "comma.html" %}
{% endfor %}
更新:@ user3748764為我們提供了一個稍微更緊湊的版本,沒有棄用的ifequal語法:
{% if not forloop.first %}{% if forloop.last %} and {% else %}, {% endif %}{% endif %}
請注意,它應該在元素之前使用,而不是之后使用。
我建議使用自定義django模板過濾器而不是自定義標簽 - 過濾器更方便,更簡單(在適當的地方,就像這里一樣)。 {{ fruits | joinby:", " }}
{{ fruits | joinby:", " }}
看起來就像我想要的那樣......使用自定義joinby
過濾器:
def joinby(value, arg):
return arg.join(value)
正如你所看到的那樣簡單!
在Django模板上,您需要做的就是在每個水果之后建立一個逗號。 一旦達到最后的果實,逗號就會停止。
{% if not forloop.last %}, {% endif %}
這是我為解決我的問題所寫的過濾器(它不包括牛津逗號)
def join_with_commas(obj_list):
"""Takes a list of objects and returns their string representations,
separated by commas and with 'and' between the penultimate and final items
For example, for a list of fruit objects:
[<Fruit: apples>, <Fruit: oranges>, <Fruit: pears>] -> 'apples, oranges and pears'
"""
if not obj_list:
return ""
l=len(obj_list)
if l==1:
return u"%s" % obj_list[0]
else:
return ", ".join(str(obj) for obj in obj_list[:l-1]) \
+ " and " + str(obj_list[l-1])
要在模板中使用它: {{ fruits|join_with_commas }}
如果你想要一個'。' 在Michael Matthew Toomim的回答結束時,然后使用:
{% if not forloop.last %}{% ifequal forloop.revcounter 2 %} and {% else %}, {% endifequal %}{% else %}{% endif %}{% if forloop.last %}.{% endif %}
此處的所有答案均不符合以下一項或多項:
and
最后一項。 這是我進入這個經典。 一,測試:
class TestTextFilters(TestCase):
def test_oxford_zero_items(self):
self.assertEqual(oxford_comma([]), '')
def test_oxford_one_item(self):
self.assertEqual(oxford_comma(['a']), 'a')
def test_oxford_two_items(self):
self.assertEqual(oxford_comma(['a', 'b']), 'a and b')
def test_oxford_three_items(self):
self.assertEqual(oxford_comma(['a', 'b', 'c']), 'a, b, and c')
而現在的代碼。 是的,它有點亂,但你會發現它不使用負索引:
from django.utils.encoding import force_text
from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe
@register.filter(is_safe=True, needs_autoescape=True)
def oxford_comma(l, autoescape=True):
"""Join together items in a list, separating them with commas or ', and'"""
l = map(force_text, l)
if autoescape:
l = map(conditional_escape, l)
num_items = len(l)
if num_items == 0:
s = ''
elif num_items == 1:
s = l[0]
elif num_items == 2:
s = l[0] + ' and ' + l[1]
elif num_items > 2:
for i, item in enumerate(l):
if i == 0:
# First item
s = item
elif i == (num_items - 1):
# Last item.
s += ', and ' + item
else:
# Items in the middle
s += ', ' + item
return mark_safe(s)
你可以在django模板中使用它:
{% load my_filters %}
{{ items|oxford_comma }}
Django沒有支持這種開箱即用的功能。 您可以為此定義自定義過濾器:
from django import template
register = template.Library()
@register.filter
def join_and(value):
"""Given a list of strings, format them with commas and spaces, but
with 'and' at the end.
>>> join_and(['apples', 'oranges', 'pears'])
"apples, oranges, and pears"
"""
# convert numbers to strings
value = [str(item) for item in value]
if len(value) == 1:
return value[0]
# join all but the last element
all_but_last = ", ".join(value[:-1])
return "%s, and %s" % (all_but_last, value[-1])
但是,如果您想處理比僅僅字符串列表更復雜的事情,則必須在模板中使用顯式的{% for x in y %}
循環。
在將其作為上下文數據發送到模板之前', '.join(['apples', 'oranges', 'pears'])
我會簡單地使用', '.join(['apples', 'oranges', 'pears'])
。
更新:
data = ['apples', 'oranges', 'pears']
print(', '.join(data[0:-1]) + ' and ' + data[-1])
你會得到apples, oranges and pears
輸出。
如果你喜歡單行:
@register.filter
def lineup(ls): return ', '.join(ls[:-1])+' and '+ls[-1] if len(ls)>1 else ls[0]
然后在模板中:
{{ fruits|lineup }}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.