Добавление RSS ленты для блога

⏱ 20 мин · 🧩 заданий: 5

Что такое RSS

RSS — XML-документ со списком последних материалов сайта. RSS-читалки (Feedly, Inoreader, встроенные в браузеры и почтовые клиенты) периодически запрашивают его и показывают новое. Читатель подписывается один раз и не пропускает статьи.

В Django для этого есть встроенный фреймворк django.contrib.syndication — устанавливать ничего не нужно.

Лента последних статей

modules/blog/feeds.py:

from django.contrib.syndication.views import Feed
from django.template.defaultfilters import truncatewords
from django.urls import reverse_lazy

from .models import Article


class LatestArticlesFeed(Feed):
    title = "Последние статьи"
    link = reverse_lazy("home")
    description = "Новые статьи на сайте"

    def items(self):
        return Article.custom.all().select_related("author")[:10]

    def item_title(self, item):
        return item.title

    def item_description(self, item):
        return truncatewords(item.short_description, 30)

    def item_pubdate(self, item):
        return item.time_create

    def item_author_name(self, item):
        return item.author.username
Элемент Назначение
title, link, description Описание самой ленты (канала)
items() Объекты, попадающие в ленту
item_title(), item_description() Заголовок и анонс элемента
item_link() Ссылка; по умолчанию item.get_absolute_url()
item_pubdate() Дата публикации — читалки сортируют по ней

Маршрут

from .feeds import LatestArticlesFeed

urlpatterns = [
    ...
    path("feeds/latest/", LatestArticlesFeed(), name="latest_articles_feed"),
]

Feed сам по себе вызываемый объект, поэтому в маршрут передаётся экземпляр, без .as_view().

Откройте /feeds/latest/ — браузер покажет XML:

<rss version="2.0">
  <channel>
    <title>Последние статьи</title>
    <link>http://127.0.0.1:8000/</link>
    <item>
      <title>Как работает ORM</title>
      <link>http://127.0.0.1:8000/articles/kak-rabotaet-orm/</link>
      <description>...</description>
      <pubDate>Sat, 24 Oct 2026 10:00:00 +0000</pubDate>
    </item>
  </channel>
</rss>

Абсолютные адреса Django строит из текущего домена (через django.contrib.sites, если оно подключено, иначе из запроса).

Лента категории

Параметр из URL передаётся в get_object():

from django.shortcuts import get_object_or_404


class CategoryArticlesFeed(Feed):
    def get_object(self, request, slug):
        return get_object_or_404(Category, slug=slug)

    def title(self, obj):
        return f"Статьи в категории «{obj.title}»"

    def link(self, obj):
        return obj.get_absolute_url()

    def description(self, obj):
        return obj.description

    def items(self, obj):
        return Article.custom.filter(category=obj)[:10]
path("feeds/category/<str:slug>/", CategoryArticlesFeed(), name="category_feed"),

Атрибуты ленты могут быть методами, принимающими obj.

Atom

Формат Atom — та же лента, другой класс генератора:

from django.utils.feedgenerator import Atom1Feed


class AtomLatestArticlesFeed(LatestArticlesFeed):
    feed_type = Atom1Feed
    subtitle = LatestArticlesFeed.description

Ссылка на ленту

В <head> шаблона main.html — для автоопределения браузерами и читалками:

<link rel="alternate" type="application/rss+xml" title="Последние статьи" href="{% url 'latest_articles_feed' %}">

И видимая ссылка в подвале:

<a href="{% url 'latest_articles_feed' %}">RSS</a>

Итог

  • RSS — встроенный django.contrib.syndication, класс Feed.
  • items() + item_*() описывают элементы; ссылка по умолчанию — get_absolute_url().
  • В urls.py — экземпляр ленты, без as_view().
  • Лента с параметром — через get_object(request, ...); Atom — feed_type = Atom1Feed.

Практика решено 0 из 5

Вы не вошли — ответы проверяются, но прогресс не сохранится. Войти или зарегистрироваться.
Задание 1 Написать код

Напишите класс LatestArticlesFeed(Feed): title = "Последние статьи", link = "/feeds/", description = "Новые статьи на сайте", метод items возвращает 10 последних опубликованных статей (Article.custom.all()[:10]), item_title — заголовок статьи.

Задание 2 Написать код

Подключите ленту в urls.py: path("feeds/latest/", LatestArticlesFeed(), name="latest_articles_feed"). Обратите внимание — у ленты нет .as_view(), передаётся экземпляр класса.

Задание 3 Один вариант ответа

Откуда лента берёт ссылку на каждую статью, если метод item_link не определён?

Задание 4 Написать код

Добавьте в <head> шаблона ссылку, по которой браузеры и RSS-читалки найдут ленту: <link rel="alternate" type="application/rss+xml" title="Последние статьи" href="{% url 'latest_articles_feed' %}">.

Задание 5 Несколько вариантов

Какие методы Feed описывают отдельный элемент ленты?

Войдите, чтобы отмечать пройденные уроки.