Использование " ,".join в Django разделяет каждый символ, а не элемент в списке

У меня есть список жанров книг, который я пытаюсь отобразить в шаблоне, используя этот код

{% if title.my_books.genre.all %}
     <li class="list-group-item">
     <kbd>Genres</kbd>
     {% for genre in title.my_books.genre.all %}
         {{genre.genre}}{% if not forloop.last %}, {% endif %}
      {% endfor %}</li> 
{% endif %}

Моя цель - отобразить элементы так Autobiography, Biography, Memoir. И приведенный выше код это делает. Однако меня попросили изменить код, чтобы использовать тег шаблона join от Django, описанный здесь https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#join

Допустим, элементы списка - ['Автобиография', 'Биография', 'Мемуары']

Очевидно, что если у меня нет этой строки {% if not forloop.last %}, {% endif %} и есть только {{genre.genre}} в цикле for,

значения будут отображаться как Autobiography Biography Memoir

Однако если я изменю приведенный выше код следующим образом, следуя документации Django:

{% if title.my_books.genre.all %}
     <li class="list-group-item">
     <kbd>Genres</kbd>
     {% for genre in title.my_books.genre.all %}
         {{ genre.genre|join:" ," }}
      {% endfor %}</li> 
{% endif %}

Вывод на шаблоне выглядит следующим образом:

A ,u ,t ,o ,b ,i ,o ,g ,r ,a ,p ,h ,y B ,i ,o ,g ,r ,a ,p ,h ,y M ,e ,m ,o ,i ,r

Как я могу правильно отобразить значения таким образом: Autobiography, Biography, Memoir используя тег шаблона join в Django? Спасибо!

В том виде, как вы сделали, он рассматривает каждый genre.genre как источник для join, поэтому он, по сути, распространяет каждый genre раздельно. Напоминаем, что в Python строки можно интерпретировать как список символов. Поэтому, если вы хотите сделать это правильно, вы должны передать жанры как список всех жанров в контексте.

просмотров:

context['genres'] = Title.my_books.genre.all()

или даже лучше добавить метод к вашей Модели:

YourModel(models.Model):
    ...
    def get_all_genres(self):
        return self.genres.all()

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

{{ yourmodel.get_all_genres|join:', ' }}

Возможно, сейчас это будет точно, потому что я не знаю ваших точных моделей/мировоззрений, но я надеюсь, что вы понимаете эти решения.

Я вижу два варианта:

Первый: Создайте список в модели и присоедините его к шаблону

В вашей модели

class YourModel(model.Model):
    
    @property
    def genres_list(self):
        return list(self.genres.all())

Ваш шаблон

Genres: {{ genre.genres_list|join:" ," }}

Второе: Генерирует str непосредственно в python и показывает его в шаблоне

В вашей модели

class YourModel(model.Model):
    
    @property
    def genres(self):
        return ", ".join(list(self.genres.all()))

Ваш шаблон

Genres: {{ genre.genres }}

Я предпочитаю второй вариант, потому что если вы хотите отображать одну и ту же строку в разных местах, нужно только включить свойство

Вернуться на верх