Это проблема, потому что, согласно документации Django по набору запросов , «QuerySet может быть сконструирован, отфильтрован, нарезан и, как правило, передан, не затрагивая базу данных». Первое, что мы с вами попробовали, это захватить первый объект из набора запросов и установить атрибут. Это не помогает, потому что сам набор запросов не оценивается, пока вы не выполните итерацию по нему: {% for instance in object_list %}
. Когда это произойдет, экземпляр модели будет снова извлечен из базы данных.
Лучшее решение, которое я вижу, - это принудительная оценка набора запросов перед обновлением экземпляра модели.
class ArticleListView(ListView):
template_name = 'article/article_list_view.html'
queryset = Article.objects.all()[:5]
def get_context_data(self, *, object_list=None, **kwargs):
# Overwriting this method to receive exactly the same arguments as the original
# https://github.com/django/django/blob/3.0.6/django/views/generic/list.py#L113
if object_list is None:
object_list = self.object_list
if not isinstance(object_list, tuple): # Force the queryset into a tuple so it's evaluated
object_list = tuple(object_list)
object_list[0].title = 'something' # Update the instance's title
return super().get_context_data(object_list=object_list, **kwargs)
Это имеет обратную сторону: article_list
не будет доступен в контексте, если вы явно не установите context_object_name = 'article_list'
в своем представлении, но вы уже не использовали эту переменную.
Я тестировал некоторые части этот код, чтобы убедиться, что моя теория верна, но я не запускал код целиком, поэтому вам, возможно, придется немного подправить, чтобы заставить его работать именно так, как вы этого хотите.