Списки, разделенные запятыми в шаблонах django
Если fruits
список ['apples', 'oranges', 'pears']
,
есть ли быстрый способ с помощью тегов шаблона django производить "яблоки, апельсины и груши"?
Я знаю, что это не сложно сделать с помощью цикла и {% if counter.last %}
заявления, но поскольку я собираюсь использовать это неоднократно, я думаю, что мне придется научиться писать пользовательские теги фильтры, и я не хочу изобретать велосипед, если это уже было сделано.
в качестве расширения, мои попытки отбросить Оксфордская Запятая (т. е. возвращение "яблоки, апельсины и груши") еще грязнее.
9 ответов:
Я бы предложил пользовательский шаблон django фильтр, а не на заказ tag -- фильтр удобнее и проще (где это уместно, как здесь).
{{ fruits | joinby:", " }}
похоже, что я хотел бы иметь для этой цели... с обычаемjoinby
фильтр:def joinby(value, arg): return arg.join(value)
, который, как вы видите, сама простота!
первый выбор: используйте существующий тег шаблона соединения.
http://docs.djangoproject.com/en/dev/ref/templates/builtins/#join
вот пример
{{ value|join:" // " }}
второй вариант: делать это в представлении.
fruits_text = ", ".join( fruits )
обеспечить
fruits_text
к шаблону для рендеринга.
вот супер простое решение. Поместите этот код в запятую.html:
{% if not forloop.last %}{% ifequal forloop.revcounter 2 %} and {% else %}, {% endifequal %}{% else %}{% endif %}
и теперь, где бы вы ни поставили запятую, включите " запятую.html " вместо этого:
{% for cat in cats %} Kitty {{cat.name}}{% include "comma.html" %} {% endfor %}
на шаблоне Django это все, что вам нужно сделать для установления запятой после каждого плода. Запятая остановится, как только она достигнет последнего плода.
{% if not forloop.last %}, {% endif %}
вот фильтр я написал, чтобы решить мою проблему:
def join_with_commas(obj_list): """Takes a list of objects and returns their unicode representations, seperated 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(unicode(obj) for obj in obj_list[:l-1]) \ + " and " + unicode(obj_list[l-1])
использовать его в шаблоне:
{{ fruits | join_with_commas }}
Если вы хотите '.- в конце ответа Майкла Мэтью Тумима используйте:
{% if not forloop.last %}{% ifequal forloop.revcounter 2 %} and {% else %}, {% endifequal %}{% else %}{% endif %}{% if forloop.last %}.{% endif %}
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 %}
цикл в вашем шаблоне.