Класс ListView
Класс ListView является одним из встроенных обобщённых классов представлений (generic views) в Django. Он предназначен для отображения списка объектов из базы данных с минимальным количеством кода. Класс автоматически выполняет запрос к модели, передаёт результат в шаблон и поддерживает пагинацию через атрибут paginate_by. Основные настройки выполняются через атрибуты класса: model или queryset для указания источника данных, template_name для выбора шаблона и context_object_name для имени переменной в контексте.
Синтаксис
from django.views.generic import ListView
from myapp.models import Article
class ArticleListView(ListView):
model = Article
template_name = "articles/list.html"
context_object_name = "articles"
paginate_by = 10
Пример
Давайте создадим представление для вывода списка всех статей с использованием класса ListView:
from django.views.generic import ListView
from myapp.models import Article
class ArticleListView(ListView):
model = Article
template_name = "articles/article_list.html"
context_object_name = "articles"
В данном примере класс автоматически выполнит запрос Article.objects.all, поместит результат в переменную контекста articles и передаст её в шаблон article_list.html.
Теперь определим URL-маршрут для этого представления:
from django.urls import path
from myapp.views import ArticleListView
urlpatterns = [
path("articles/", ArticleListView.as_view(), name="article_list"),
]
Шаблон article_list.html для отображения списка статей:
<h1>Articles</h1>
<ul>
{% for article in articles %}
<li>{{ article.title }} - {{ article.published_date }}</li>
{% empty %}
<li>No articles found.</li>
{% endfor %}
</ul>
Пример
Давайте настроим ListView для отображения списка статей с пагинацией по 10 записей на странице:
from django.views.generic import ListView
from myapp.models import Article
class ArticleListView(ListView):
model = Article
template_name = "articles/article_list.html"
context_object_name = "articles"
paginate_by = 10
При использовании пагинации в контекст также добавляются переменные paginator, page_obj и is_paginated. Обновлённый шаблон с пагинацией:
<h1>Articles</h1>
<ul>
{% for article in articles %}
<li>{{ article.title }} - {{ article.published_date }}</li>
{% empty %}
<li>No articles found.</li>
{% endfor %}
</ul>
{% if is_paginated %}
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
<a href="?page=1">First</a>
<a href="?page={{ page_obj.previous_page_number }}">Previous</a>
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">Next</a>
<a href="?page={{ page_obj.paginator.num_pages }}">Last</a>
{% endif %}
</span>
</div>
{% endif %}
Пример
Давайте переопределим метод get_queryset для фильтрации статей по статусу и сортировки по дате создания:
from django.views.generic import ListView
from myapp.models import Article
class PublishedArticleListView(ListView):
model = Article
template_name = "articles/published_articles.html"
context_object_name = "articles"
paginate_by = 20
def get_queryset(self):
return Article.objects.filter(status="published").order_by("-created_at")
В данном примере метод get_queryset возвращает только опубликованные статьи, отсортированные по дате создания в обратном порядке (сначала новые). Результат выполнения кода:
[<Article: How to use ListView>, <Article: Django basics>, <Article: Advanced queries>]
Смотрите также
-
класс
DetailView,
который отображает одну запись модели -
атрибут
queryset,
который задаёт начальный набор данных -
атрибут
paginate_by,
который включает пагинацию списка -
метод
get_queryset,
который переопределяет логику получения данных