SEO 101: Creating custom sitemap using django

Published: 07/25/2019

I must agree I was pretty impatient to use the codesnippet plugin on this editor.


Well, a couple of days back I was trying to find a way to create sitemaps in django. One way is to use a crawler to crawl all your pages and generate the sitemap. But that's a bad solution as you need to manually update it everytime. We are looking for something more dynamic. Thanks to django, it already has a base class which helps in generation of sitemaps.

Let's start with the We add the url for sitemap.xml and add the sitemaps object specifying which sitemap class to use. We can add multiple sitemaps together, and django will render it together for you.

from myblog import sitemaps

urlpatterns = [
    url(r'^sitemap.xml', sitemap, {
      'sitemaps': {
        'blogs': sitemaps.BlogSitemap

Then let's go on to

import urllib.parse

from django.contrib.sitemaps import Sitemap
from django.conf import settings

from aldryn_newsblog.cms_appconfig import NewsBlogConfig
from aldryn_newsblog.models import Article

from cms.models import Page

class BlogSitemap(Sitemap):
    priority = 0.5

    def items(self):
        urls = ['/']
        blogs = NewsBlogConfig.objects.all()
        for blog in blogs:
            p = Page.objects.get(application_namespace=blog.namespace, publisher_is_draft=False)
            articles = Article.objects.filter(app_config=blog).all()
            for i in range(len(articles) // 5):
                urls.append(f'{p.get_absolute_url()}?page={i + 2}')
            for article in articles:
        return urls

    def location(self, obj):
        return obj

Generally items() should return an iterable of objects which will have a method called get_absolute_url() which will give the url, but django gives you the option to specify their locations too using the loaction(item) method. We are using this cleverly to just return a list of urls in the items method and then returning the item in the location method as the item is nothing but a string which is the url. In this way we can include pages like /blog-name/?page=2 which aren't returned by any object's get_absolute_url() method.