Why a sitemap and a feed
A crawler follows links, so deep or new pages are found late. sitemap.xml is an explicit list of URLs. An RSS/Atom feed publishes the same content in a machine-readable form. Django provides all of it in django.contrib.
| Tool | URL | Audience |
|---|---|---|
Sitemap | /sitemap.xml | search crawlers |
Feed | /feeds/rss/ | readers and aggregators |
| robots.txt | /robots.txt | all crawlers |
Setup
Add django.contrib.sites, django.contrib.sitemaps and django.contrib.syndication to INSTALLED_APPS and set SITE_ID = 1. Without sites Django uses the host of the current request, but with sites the domain lives in one place.
# settings.py
INSTALLED_APPS = [
# ...
"django.contrib.sites",
"django.contrib.sitemaps",
"django.contrib.syndication",
"blog",
]
SITE_ID = 1⚠️ After
migratethe defaultSiterecord isexample.com. Change it to your real domain in the admin or shell:Site.objects.update(domain="example.org", name="Example").
The Sitemap class
The model needs get_absolute_url(). The Sitemap items() method returns the objects and lastmod() returns the change date.
# blog/models.py
from django.db import models
from django.urls import reverse
class Post(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
body = models.TextField()
published = models.BooleanField(default=False)
published_at = models.DateTimeField(null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True)
def get_absolute_url(self):
return reverse("blog:post-detail", kwargs={"slug": self.slug})# blog/sitemaps.py
from django.contrib.sitemaps import Sitemap
from django.urls import reverse
from .models import Post
class PostSitemap(Sitemap):
changefreq = "weekly"
priority = 0.8
protocol = "https"