Program Tip

장고 템플릿의 쉼표로 구분 된 목록

programtip 2020. 11. 12. 20:05
반응형

장고 템플릿의 쉼표로 구분 된 목록


경우 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:", " }}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 %}

', '.join(['apples', 'oranges', 'pears'])컨텍스트 데이터로 템플릿에 보내기 전에 사용 합니다.

최신 정보:

data = ['apples', 'oranges', 'pears']
print(', '.join(data[0:-1]) + ' and ' + data[-1])

당신은 얻을 것이다 apples, oranges and pears출력을.


여기에있는 모든 답변은 다음 중 하나 이상에 실패합니다.

  • 표준 템플릿 라이브러리 (ack, top answer!)에있는 무언가를 다시 작성합니다.
  • and마지막 항목 에는 사용하지 않습니다 .
  • 직렬 (옥스포드) 쉼표가 없습니다.
  • 그들은 django 쿼리 세트에서 작동하지 않는 부정적인 인덱싱을 사용합니다.
  • 그들은 보통 끈 위생을 제대로 처리하지 않습니다.

이 캐논에 대한 나의 입장입니다. 첫째, 테스트 :

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')

And now the code. Yes, it gets a bit messy, but you'll see that it doesn't use negative indexing:

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)

You can use this in a django template with:

{% load my_filters %}
{{ items|oxford_comma }}

Django doesn't have support for this out-of-the-box. You can define a custom filter for this:

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])

However, if you want to deal with something more complex than just lists of strings, you'll have to use an explicit {% for x in y %} loop in your template.


If you like one-liners:

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

and then in the template:

{{ fruits|lineup }}

I think the simplest solution might be:

@register.filter
def comma_list(p_values: Iterable[str]) -> List[str]:
    values = list(p_values)
    if len(values) > 1:
        values[-1] = u'and %s' % values[-1]
    if len(values) > 2:
        return u', '.join(values)
    return u' '.join(values)

참고URL : https://stackoverflow.com/questions/1236593/comma-separated-lists-in-django-templates

반응형