Django Sitemap: Using the Built-in Sitemaps Framework
Django ships with a built-in sitemaps framework in django.contrib.sitemaps. Unlike most frameworks, you do not need a third-party package. You define sitemap classes for each type of content, wire them into your URL configuration, and Django serves them at /sitemap.xml automatically. The framework also supports sitemap indexes out of the box.
Basic Setup
Add django.contrib.sitemaps to INSTALLED_APPS and django.contrib.sites if not already present. Then define a sitemap class and wire it up:
Each item returned by items() must implement get_absolute_url(). Django calls this method on each object to generate the URL in the sitemap. If your model does not have get_absolute_url(), either add it or override the location() method in your sitemap class.
The Sites Framework Requirement
Django sitemaps use the Sites framework to determine your domain name. You must have a Site record in your database with your correct production domain. Go to the Django admin, then Sites, and update the example.com entry to your actual domain. If the Sites framework is not configured correctly, all sitemap URLs will use example.com instead of your real domain - a common mistake that causes the sitemap to be rejected by Google.
Caching Django Sitemaps
Django sitemaps are generated on every request by default. For large sites, this is expensive. Use Django cache_page decorator or the cached_sitemap view wrapper: from django.contrib.sitemaps.views import sitemap and wrap it with cache_page(60 * 60 * 24) to cache for 24 hours. Invalidate the cache when content changes using Django signals - send a cache clear signal on post_save for your content models.
Common Django Sitemap Issues
DisallowedHost error when generating sitemap: This happens if your ALLOWED_HOSTS setting does not include the domain being used to access the sitemap. Make sure your production domain is in ALLOWED_HOSTS.
get_absolute_url not defined: Django throws a ImproperlyConfigured error if items in your sitemap do not have get_absolute_url(). Add the method to your model or override location() in your Sitemap class to return the correct URL path for each object.