Добавление RSS ленты для блога
Что такое 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
Напишите класс LatestArticlesFeed(Feed): title = "Последние статьи", link = "/feeds/",
description = "Новые статьи на сайте", метод items возвращает 10 последних опубликованных статей
(Article.custom.all()[:10]), item_title — заголовок статьи.
from django.contrib.syndication.views import Feed
class LatestArticlesFeed(Feed):
title = "Последние статьи"
link = "/feeds/"
description = "Новые статьи на сайте"
def items(self):
return Article.custom.all()[:10]
def item_title(self, item):
return item.title
Подключите ленту в urls.py: path("feeds/latest/", LatestArticlesFeed(), name="latest_articles_feed").
Обратите внимание — у ленты нет .as_view(), передаётся экземпляр класса.
urlpatterns = [
path("feeds/latest/", LatestArticlesFeed(), name="latest_articles_feed"),
]
Откуда лента берёт ссылку на каждую статью, если метод item_link не определён?
Добавьте в <head> шаблона ссылку, по которой браузеры и RSS-читалки найдут ленту:
<link rel="alternate" type="application/rss+xml" title="Последние статьи" href="{% url 'latest_articles_feed' %}">.
<link rel="alternate" type="application/rss+xml" title="Последние статьи" href="{% url 'latest_articles_feed' %}">
Какие методы Feed описывают отдельный элемент ленты?
Войдите, чтобы отмечать пройденные уроки.