How to Create a Dynamic Django Sitemap

Aug. 31, 2020, 5:13 p.m.
Django Production SEO · 6 min read
How to Create a Dynamic Django Sitemap
Last Modified: April 22, 2021, 12:53 p.m.

A sitemap is an XML file on your website that search engines read to intelligently crawl your site. It not only provides information about the pages and files you find important, but it also states when the page was last updated and how often the page is changed.

If you are using Django, create your Django sitemap automatically with the sites and sitemap frameworks.

 

Install the Django sites app

env > mysite > mysite > settings.py

INSTALLED_APPS = [
    'main.apps.MainConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',    #add sites to installed apps
]

SITE_ID = 1   #define the site id

First, install the sites app. Then define the SITE_ID in the settings. The sites framework will be used to define the name of the site in the sitemap. 

 

Run migrations

macOS Terminal

(env)User-Macbook:mysite user$ python3 manage.py migrate

Windows Command Prompt

(env)C:\Users\Owner\desktop\env\mysite> py manage.py migrate

Run migrate in the command prompt to add the sites table to the database.

 

Create a superuser

macOS Terminal

(env)User-Macbook:mysite user$ python3 manage.py createsuperuser
Username (leave blank to use 'owner'): admin
Email address:
Password: *****
Password (again): *****
Superuser created successfully.

(env)User-Macbook:mysite user$ python3 manage.py runserver

Windows Command Prompt

(env) C:\Users\Owner\Desktop\Code\env\mysite>py manage.py createsuperuser
Username (leave blank to use 'owner'): admin
Email address: 
Password: *****
Password (again): *****
Superuser created successfully.

(env) C:\Users\Owner\Desktop\Code\env\mysite>py manage.py runserver

If you haven't already, create a superuser so you can access the Django administration built in your project.

 

Log in to the Django administration

django.contrib.sites registers a signal handler that creates a default site named example.com. You will need to correct the name and domain of your Django project by logging in to the Django admin at http://127.0.0.1:8000/admin/

Find the link Sites and click it.

Site link in the django admin

You will then see a site domain name and display name listed, both of which should be changed to the appropriate website name.

For development, use the localhost 127.0.0.1:8000. For production, change the names to your actual domain name. 

Site listed in Django admin

 

Install the Django sitemap app

env > mysite > mysite > settings.py

INSTALLED_APPS = [
    'main.apps.MainConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sitemaps',   #add Django sitemaps to installed apps
]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

Now that we have defined the name of the site, we can use the Django sitemap framework.

To install the Django sitemap app, add 'django.contrib.sitemaps' to INSTALLED_APPS. Then scroll down to TEMPLATES making sure DjangoTemplates is listed (it should be there by default) and the APP_DIRS is set to True.

 

Create a Django sitemap file

env > mysite > main > (New File) sitemaps.py

from django.contrib.sitemaps import Sitemap
from .models import Article
 
 
class ArticleSitemap(Sitemap):
    changefreq = "weekly"
    priority = 0.8
    protocol = 'http'

    def items(self):
        return Article.objects.all()

    def lastmod(self, obj):
        return obj.article_published
        
    def location(self,obj):
        return '/blog/%s' % (obj.article_slug)

Creating a Django sitemap is similar to creating a Django model. First, create a new file called sitemaps.py in your app's folder. This is the folder with models.py and views.py.

Then import the Sitemap class from django.contrib.sitemaps at the top of the file. Also import the model containing all of the articles/pages you want on the sitemap, in this case, the model Article.

Next, create a sitemap class named ArticleSitemap that extends Sitemap class.

We can then add the attributes changefreq, priority, and protocol

changefreq is how frequently the content on the page changes. The value can be:

  • 'always'
  • 'hourly'
  • 'daily'
  • 'weekly'
  • 'monthly'
  • 'yearly'
  • 'never'

priority is the importance of the pages to the other pages on your site. The value can be anywhere from 0.0 to 1.0

protocol is either 'https' or 'http'. In this case, we will use HTTP given the localhost domain is http://127.0.0.1:8000

The items() method returns a list of all of the model objects we want to be listed in the Django sitemap.

The lastmod() method returns the last time the model object was modified, meaning you need to return a defined publication date field specified in the model for it to work properly.

Finally, the location() method returns the URL location of the article. By default, the Django sitemap framework calls get_absolute_url().

So if your article URLs is anything other than http://127.0.0.1:8000/name-of-article, you need to add the location() method and return the appropriate slugs listed before the article slug.

As per the example above, the URL location is now http://127.0.0.1:8000/blog/name-of-article.

 

Add the Django sitemap URL

env > mysite > main > urls.py

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

app_name = "main"

sitemaps = {
    'blog':ArticleSitemap
}

urlpatterns = [
    path("", views.homepage, name="homepage"),
    path('sitemap.xml', sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap'),

]

The last thing that needs to be done to view your Django sitemap is to add its URL to the list of app URLs. Import sitemap and ArticleSitemap from the appropriate files.

Then add a Django sitemap dictionary that maps to the sitemap class ArticleSitemap. Finally, add the URL pattern that points to the Django sitemap. 

 


 

Adding Static Pages to the Dynamic Django Sitemap

env > mysite > main > sitemaps.py

from django.contrib.sitemaps import Sitemap
from .models import Article
from django.urls import reverse

...


class StaticSitemap(Sitemap):
    changefreq = "yearly"
    priority = 0.8
    protocol = 'https'

    def items(self):
        return ['main:homepage_view', 'main:contact_view']

    def location(self, item):
        return reverse(item)

You can also add static pages such as /contact or /about to your dynamic Django sitemap. 

Go to the sitemaps.py file, and add a new function called StaticSitemap that extends the Sitemap class.

Set the changefreq, priority, and protocol then add the items() method that returns a list of app_name:url_name

Next, import the reverse() method from Django URLs at the top of the file.

Add the location() method that returns the URL to complete the static Django sitemap function.

 

Note, you'll want to refer to your main > urls.py file for the correct URL names. 

 

env > mysite > main > urls.py

from django.urls import path
from . import views
from django.contrib.sitemaps.views import sitemap
from .sitemaps import ArticleSitemap, StaticSitemap #import StaticSitemap

app_name = "main"

sitemaps = {
    'blog':ArticleSitemap,
    'static':StaticSitemap #add StaticSitemap to the dictionary
}

urlpatterns = [
    path("", views.homepage, name="homepage"),
    path('sitemap.xml', sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap'),

]

Return the main > urls.py and import the new sitemap at the top of the file. 

Then add the StaticSitemap to the sitemap dictionary.

 


 

View the Django sitemap

The Django sitemap is now available at http://127.0.0.1:8000/sitemap.xml/. When you go to this domain, it should list all of the URLs defined in the Article model along with the attributes added in sitemaps.py.

Django Sitemap Example

Sitemap






Post a Comment
Join the community

2 Comments
Abas March 1, 2021, 2:50 a.m.

Great Article, Jaysha. How do you include sitemaps for other pages such as home and about us into the above sitemap. Thanks

Jaysha replying to Abas March 1, 2021, 3:23 p.m.

Thanks for the feedback Abas. I've updated the article to now include instructions on how to add static pages to the Django dynamic sitemap. Let me know if you have further questions.

2
Jaysha
Written By
Jaysha
Hello! I enjoy learning about new CSS frameworks, animation libraries, and SEO.