Create html or xml sitempa for Django app

If you are creating any content based website, it is utmost important to have a sitemap.   At first it looks like sitemap creation is complex using Django but if you understand the process its fairly simple. You can follow below steps to create simple sitemap.xml

Step#1 Config changes.

Add 'django.contrib.sitemaps', in INSTALLED_APPS section of settings.py
Also ensure following settings for TEMPLATES

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            BASE_DIR + '/templates/', # add this line
        ],
        'APP_DIRS': True,

Step#2 Create sitemap.py

Now cd to subapp directory and create file sitemaps.py as below

from django.contrib.sitemaps import Sitemap
from .models import Post
 
 
class PostSitemap(Sitemap):    
    changefreq = "monthly"
    priority = 0.9
 
    def items(self):
        return Post.objects.all()
 
    def lastmod(self, obj):
        return obj.created_on

changefreq can be hourly, monthly, never etc.

Most important point to be noted here. Whichever data model you are using, make sure it has function get_absolute_url()  defined.
for example

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')
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)
    category = models.ForeignKey(Category, on_delete = models.CASCADE,verbose_name="Category",default=None,blank=True)
    updated_on = models.DateTimeField(auto_now= True)
    tags = models.ManyToManyField(Tag, related_name='rel_posts',default=None,blank=True)
    featured_image = models.ImageField(upload_to='img', blank=True, null=True)

    class Meta:
        ordering = ['-created_on']

    def get_absolute_url(self): #this is added for sitemap
        return '/'+self.slug
    def __str__(self):
        return self.title

Now make changes into blog/urls.py

from django.urls import path
from . import views
from django.contrib.sitemaps.views import sitemap
from .sitemaps import PostSitemap

sitemaps = {
    'posts': PostSitemap
}

app_name = 'blog'
urlpatterns = [
    path('', views.index, name='index'),  
    path('sitemap.xml', sitemap, {'sitemaps' : sitemaps } , name='sitemap'),  
]

Now if you try to access sitemap.xml, you can see it

http://127.0.0.1:8000/sitemap.xml/

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<urlset>
  <url>
    <loc>https://www.fintrekking.com/finance-is-everything</loc>
    <lastmod>2020-04-18</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.9</priority>
  </url>
</urlset>

Please notethat this siitemap is accessible from subapp. Either you need to make this subapp accessible on main url or this sitempa will be available at url something like below

http://127.0.0.1:8000/blog/sitemap.xml/

Please let me know if this works for you or if you faced any issue while making this work.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.