Класс ListView

Класс ListView является одним из встроенных обобщённых классов представлений (generic views) в Django. Он предназначен для отображения списка объектов из базы данных с минимальным количеством кода. Класс автоматически выполняет запрос к модели, передаёт результат в шаблон и поддерживает пагинацию через атрибут paginate_by. Основные настройки выполняются через атрибуты класса: model или queryset для указания источника данных, template_name для выбора шаблона и context_object_name для имени переменной в контексте.

Синтаксис

pythonfrom 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:

pythonfrom 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-маршрут для этого представления:

pythonfrom django.urls import path
from myapp.views import ArticleListView

urlpatterns = [
  path("articles/", ArticleListView.as_view(), name="article_list"),
]

Шаблон article_list.html для отображения списка статей:

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 записей на странице:

pythonfrom 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. Обновлённый шаблон с пагинацией:

html<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 для фильтрации статей по статусу и сортировки по дате создания:

pythonfrom 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 возвращает только опубликованные статьи, отсортированные по дате создания в обратном порядке (сначала новые). Результат выполнения кода:

python[<Article: How to use ListView>, <Article: Django basics>, <Article: Advanced queries>]

Смотрите также

  • класс DetailView,
    который отображает одну запись модели
  • атрибут queryset,
    который задаёт начальный набор данных
  • атрибут paginate_by,
    который включает пагинацию списка
  • метод get_queryset,
    который переопределяет логику получения данных