Django. Объединение полей ManytoMany для последующей сортировки
Подскажите пожалуйста, есть два класса Book и Author. У книги может быть как много авторов, так и ни одного.
class Author(models.Model):
name= models.CharField()
class Book(models.Model):
title = models.CharField()
author = models.ManyToManyField(Author, blank=True)
Соответственно требуется объединить значения полей 'name' из Author и 'title' из Book для корректной сортировки по алфавиту и фильтрации по первой букве для алфавитного списка:
- Сахаров С., Солевой С. Судьбы родины.
- Сборник статей
- Суворов Г.М. Ох уж эти сказки
Пробовал "Concat" во 'views.py', но он игнорирует пустые поля в Author и ставит книги без автора в самый верх списка. Объединял через функцию в 'models.py' и в шаблоне сортировал через |dictsort:"", но сортирует криво при включенной пагинации, да и не хочется логику в шаблоне держать. В общем, прошу совета. Спасибо
Примерно так:
for book in Book.objects.all():
result_str = ', '.join(
[book.autor.all().values_list('name', flat=True)]
) + ' ' + book.name
print(result_str)
Для удобства, в модель book можно добавить проперти:
@property
def autors_str(self):
return ', '.join([self.autor.all().values_list('name', flat=True)])
Нужно было все-таки действовать через Concat
во views.py
, но обращаться не к полю author
модели Book
, а идти через модель Author
к его полю name
.
books_list=Book.objects.annotate(FullTitle=Concat('author__name', 'title')).order_by('FullTitle')
Один нюанс: у книг с несколькими авторами создаются дубликаты (в количестве, равном количеству авторов). Но для алфавитного каталога так и должно быть - сортируются они каждый в свою букву. Т.е. книга "Иванов И., Петров П. История игрушек" будет лежать и в букве И, и в букве П.