Списки с запятыми в шаблонах django

Если fruits – это список ['apples', 'oranges', 'pears']

есть ли быстрый способ использовать теги шаблона django для создания «яблок, апельсинов и груш»?

Я знаю, что это не сложно сделать с помощью операторов цикла и {% if counter.last %} , но поскольку я буду использовать это повторно, я думаю, что мне нужно научиться писать пользовательские теги фильтры, и я не хочу изобретать велосипед, если это уже сделано.

В качестве продолжения мои попытки сбросить Оксфордскую запятую (то есть вернуть «яблоки, апельсины и груши») даже беспорядочны.

  • Python 3.5 vs Python 2.7: Модули, импортирующие подмодули
  • Django возвращает ошибку 403 при отправке запроса POST
  • Как избежать использования метода AppConfig.ready (), выполняющегося дважды в Django
  • Имитация нажатий клавиш в python с использованием pywin32
  • Можно ли уменьшить глубину изображения с помощью PIL?
  • Можно ли настроить проверку ошибок Pylint?
  • SQL Alchemy ORM возвращает один столбец, как избежать обычной обработки сообщений
  • Самый простой способ запустить сценарий ожидания из python
  • 8 Solutions collect form web for “Списки с запятыми в шаблонах django”

    Я бы предложил специальный фильтр шаблонов django, а не специальный тег. Фильтр более удобен и проще (где это необходимо, например, здесь). {{ fruits | joinby:", " }} {{ 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 шаблону для рендеринга.

    Вот супер простое решение. Поместите этот код в файл 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 %} 

    На шаблоне 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 }} {{ 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 %} в вашем шаблоне.

    Если вам нравятся однострочные:

     @register.filter def lineup(ls): return ', '.join(ls[:-1])+' and '+ls[-1] if len(ls)>1 else ls[0] 

    а затем в шаблоне:

     {{ fruits|lineup }} 
    Python - лучший язык программирования в мире.