Фильтр шаблонов Django для создания списка элементов, которые объединяются запятыми и заканчиваются на «и» - PullRequest
4 голосов
/ 05 августа 2010

Я чувствую, что пишу что-то, что уже должно существовать.

Есть ли в Django шаблонный фильтр, который объединяет список элементов в запятых и местах и ​​'и' перед последним?

Например:

a = ['foo',]
b = ['bar', 'baz',]
c = a + b
d = c + ['yourmom',]

Фильтр, который я ищу, будет отображать каждый список следующими способами:

a будет отображать 'foo'.
b будет отображать 'bar and baz'.
c будет отображать «foo, bar и baz».
d будет отображать 'foo, bar, baz и yourmom'.

ВОПРОС 1: Есть ли что-то, что уже делает это?


Я пытался написать это сам, и он ломается в двух местах:

Мой код: http://pastie.org/private/fhtvg5tchtwlnrdyuoyeja

ВОПРОС 2: Он разбивается на forloop.counter & tc.author.all | length. Пожалуйста, объясните, почему они недействительны.

Ответы [ 4 ]

15 голосов
/ 05 августа 2010

Вы можете сделать это в своем шаблоне:

{% for item in list %}
    {% if forloop.first %}{% else %}
        {% if forloop.last %} and {% else %}, {% endif %}
    {% endif %}{{item}}
{% endfor %}

Для ясности добавлено разрывов строк: удалите их, чтобы избежать нежелательных пробелов в выводе:

{% for item in list %}{% if forloop.first %}{% else %}{% if forloop.last %} and {% else %}, {% endif %}{% endif %}{{item}}{% endfor %}

Редактировать: Изменен код.Спасибо Эрику Фортину за то, что он заметил, что я запутался.

0 голосов
/ 11 февраля 2017

Я решил эту проблему, используя псевдоклассы css ::before и ::after.Я дал каждому предмету класс item, а затем сделал следующее:

.item:not(:last-child)::after{
    content: ", ";
}
.item:last-child::before{
    content: "and ";
}
.item:last-child::after{
    content: ".";
}

Это не решение Django, но всегда полезно размешать идеи

0 голосов
/ 31 июля 2011

Вот один, который я написал с функцией «максимум элементов»:

useserialcomma = True

def listify(values, maxitems=4):
    sercomma = ',' if useserialcomma else ''
    l = len(values)
    if l == 0:
        return ''
    elif l == 1:
        return values[0]
    elif l == 2:
        return values[0] + ' and ' + values[1]
    elif l <= maxitems:
        return ', '.join(values[:l-1]) + sercomma + ' and ' + values[-1]
    else:
        andmoretxt = ' and %d more' % (l - maxitems)
        return ', '.join(values[:maxitems]) + andmoretxt

Этот фильтр позволяет указать максимальное количество элементов, которые вы хотите отобразить.Итак, учитывая этот список:

myitems = ['foo', 'bar', 'baz', 'barn', 'feast', 'pizza']

этот код в вашем шаблоне:

{{ myitems|listify:3 }}

производит:

foo, bar, baz and 3 others
0 голосов
/ 05 августа 2010

Попробуйте фильтр вот так (не тестировался):

def human_join(values):
    out = ', '.join(values[:-1])
    if out:
        out += ' and '

    if values:
        out += values[-1]

    return out
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...