Ввод пользовательских данных в Django Queryset перед передачей в шаблон

Каким образом лучше всего добавлять или вводить дополнительные данные в Django QuerySet?

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

models.py

class Book(models.Model):
    name = models.CharField(max_length=64)

book_list.html

{% for book in objects %}
    {{ book.name }} - {{ book.special_result }}
{% endfor %}

views.py

class BookListView(ListView):
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        books = self.object_list
        
        for book in books:
            book.special_result = do_special_calculation(foo=bar)

        context['books'] = books

        return context

Представьте себе, что метод do_special_calculation() не может быть вычислен в шаблоне или в качестве параметра модели, потому что ему необходимо передать переменную foo.

Этот код не достигает желаемого результата - сделать значение book каждого special_result доступным из шаблона, потому что переменная book перезаписывается с каждой итерацией цикла for. Все решения, которые мне удалось найти, включают в себя создание нового словаря параллельно с QuerySet, передачу его в шаблон и одновременное обращение к ним обоим в шаблоне, что приводит к очень некрасивому коду.

Я также не хочу сохранять результат do_special_calculations() обратно в базу данных по целому ряду причин (эффективность, потенциально устаревшие данные, невозможность простого сохранения объекта).

Каким образом лучше всего сделать специальный расчет каждой записи доступным в шаблоне?

В конце концов я решил эту проблему, создав пустой список и используя setattr() в каждом элементе. Вот пример исправленного кода:

class BookListView(ListView):
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        books = self.object_list

        book_list = []
        
        for book in books:
            special_result = do_special_calculation(foo=bar)
            setattr(book, "special_result", special_result)
            book_list.append(book)

        context['books'] = book_list

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