Support Our Site

To ensure we can continue delivering content and maintaining a free platform for all users, we kindly request that you disable your adblocker. Your contribution greatly supports our site's growth and development.

Creating Feeds with Django

3 min read

Table of Contents

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/


DJANGO

Latest Articles

Latest from djangocentral

How to Use Subquery() in Django With Practical Examples

In the realm of web development, Django stands as a powerful and versatile framework for building robust applications. One of the key aspects of developing efficient and optimized web applications is handling database queries effectively. In this article…
Read more →

4 min read

DRF Serializer: Handling OrderedDict and Converting It to a Dictionary or JSON

In Django Rest Framework (DRF) tests, when you access serializer.data, you might encounter an OrderedDict instead of a regular dictionary. This behavior is intentional and reflects the design of DRF's serialization process.Understanding the Problem The u…
Read more →

3 min read

Django Rest Framework CheetSheet: Mastering API Development

Django Rest Framework (DRF) is a powerful toolkit that makes building robust and scalable web APIs with Django a breeze. Whether you're a seasoned Django developer or a newcomer, having a comprehensive cheat sheet at your disposal can be a game-changer. …
Read more →

5 min read

How to Perform NOT Queries in Django ORM

In Django, performing NOT queries allows you to exclude certain records from the query results based on specific conditions. The NOT operator, represented by the tilde (~) when used in conjunction with the Django ORM's Q object, helps you construct compl…
Read more →

3 min read