Django ships with built-in syndication feed generating framework, which is used to generate dynamic Atom and RSS feeds.
RSS is an abbreviation for Really Simple Syndication, it's a way to have information delivered to you instead of you having to go find it. RSS is basically a structured XML document that includes full or summarized text along with other metadata such as published date, author name, etc.
Creating RSS Feeds with Django
In this article, we are going to generate feeds for a blog application following is the models.py
file.
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(
User, on_delete=models.CASCADE, related_name="blog_posts"
)
updated_on = models.DateTimeField(auto_now=True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
class Meta:
ordering = ["-created_on"]
def __str__(self):
return self.title
def get_absolute_url(self):
from django.urls import reverse
return reverse("post_detail", kwargs={"slug": str(self.slug)})
Create a new file feeds.py
inside the application directory.
from django.contrib.syndication.views import Feed
from django.template.defaultfilters import truncatewords
from .models import Postfrom django.urls import reverse
class LatestPostsFeed(Feed):
title = "My blog"
link = ""
description = "New posts of my blog."
def items(self):
return Post.objects.filter(status=1)
def item_title(self, item):
return item.title
def item_description(self, item):
return truncatewords(item.content, 30)
# Only needed if the model has no get_absolute_url method
# def item_link(self, item):
# return reverse("post_detail", args=[item.slug])
The title, link, and description correspond to the standard RSS <title>
, <link>
and <description>
elements, respectively.
The items()
method retrieves the objects to be included in the feed. The item_title()
and item_description()
methods receive each object returned by items()
and return the title and description for each item. We used truncatewords
built-in template filter to build the description of the blog post with the first 30 words.
In order to retrieve links of items, you must either implement get_absolute_url()
in the models all item_link()
in the Post feed class.
Next map the feed in urls.py
file.
from .feeds import LatestPostsFeed
urlpatterns = [
path("feed/rss", LatestPostsFeed(), name="post_feed"),
]
Now Django will build RSS 2.0 feed at /feed/rss
Save the file run the server and navigate to http://127.0.0.1:8000/feed/rss
you should see the XML file.
Use this XML Formatter tool to see the feed in a user-friendly form, here is an example feed.
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>My blog</title>
<link/>http://127.0.0.1:8000
<description>
New posts of my blog.</description>
<atom:link href="http://127.0.0.1:8000/feed/rss" rel="self">
</atom:link>
<language>en-us</language>
<lastbuilddate>Fri, 03 Jan 2020 15:22:32 +0000</lastbuilddate>
<item>
<title>Second Post</title>
<link/>http://127.0.0.1:8000/second-post/
<description>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam feugiat velit diam. Etiam ut ex convallis, feugiat odio sit amet, mattis dolor. Suspendisse velit neque, sollicitudin placerat rhoncus ut, semper …</description>
<guid>http://127.0.0.1:8000/second-post/</guid>
</item>
<item>
<title>My First Ever Post</title>
<link/>http://127.0.0.1:8000/my-first-ever-post/
<description>
This is my first ever blog post</description>
<guid>http://127.0.0.1:8000/my-first-ever-post/</guid>
</item>
</channel>
</rss>
By default, Django produces RSS 2.0 Feeds to generate Atom feeds you can assign feed_type
to Atom.
from django.utils.feedgenerator import Atom1Feed
class MyFeed(Feed):
feed_type = Atom1Feed
To explore more visit - https://docs.djangoproject.com/en/3.0/ref/contrib/syndication/