Django has a sitemap framework that allows you to generate it dynamically. A sitemap is an XML file that tells search engines what pages are on the site, their relevance, and how often they are updated. It can be used to help search engine crawlers index all content. This framework relies on django.contrib.sites
, which allows you to objectify individual sites of an entire project. This is very handy if you need to run multiple sites with a single Django project. To install the framework, you need to activate the sites
and sitemap
applications in the project. Edit the settings.py
file of the project and add django.contrib.sites
and django.contrib.sitemaps
to INSTALLED_APPS
. Also define a new setting with SITE_ID
:
SITE_ID = 1
# Application definition
INSTALLED_APPS = [
# ..
'django.contrib.sites',
'django.contrib.sitemaps',
]
Now run this command to create Django site application tables in the database:
python manage.py migrate
The output should be as follows:
Applying sites.0001_initial... OK
Applying sites.0002_alter_domain_unique... OK
The sites
application is now synchronized with the database. Create a new file in the blog
application folder and name it sitemap.py
. Open the file and add the following code:
from django.contrib.sitemaps import Sitemap
from .models import Post
class PostSitemap(Sitemap)
changefreq = 'weekly'
priority = 0.9
def items(self)
return Post.published.all()
def lastmod(self, obj)
return obj.updated
Let’s create our own sitemap by inheriting the Sitemap
class of the sitemaps
module. The attributes changefreq
and priotiy
indicate how often pages with posts are changed and how relevant they are to the site (the maximum value is 1). The items()
method returns a QuerySet of objects to include in the database. By default, Django calls the get_absolute_url()
method for each object to get the URL. Recall the method you created to get canonical URLs for posts. If you want to define a URL for each object, you can add a location
method to the sitemap class. The lastmod
method gets each object that the items()
method returned and in turn returns the date when that object last changed. Both changefreq
and priority
can be methods as well as attributes. The full site map framework is described in the Django documentation at https://docs.djangoproject.com/en/2.0/ref/contrib/sitemaps/. All that remains is to add the sitemap URL. Edit the main urls.py
file of the project and add a link.
# mysite/urls.py
from django.urls import path, include
from django. contrib admin
from django.contrib.sitemaps.views import sitemap
from blog.sitemap import PostSitemap
sitemaps = {
'posts': PostSitemap,
}
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls', namespace='blog')),
path('sitemap.xml', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap')
]
In this code, the necessary imports have been included, and a sitemap dictionary has been defined. A URL template has also been defined that leads to sitemap.xml
and uses the sitemap view. Start the development server and type in https://127.0.0.1:8000/sitemap.xml in your browser. The following XML output should appear:
<urlset>
<url>
<loc>https://example.com/blog/2020/2/2/markdown-post/</loc>
<lastmod>2020-02-02</lastmod>
<changefreq>weekly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>
https://example.com/blog/2019/12/14/ai-community-needs-take-responsibility-its-technology-and-its-actions/
</loc>
<lastmod>2019-12-28</lastmod>
<changefreq>weekly</changefreq>
<priority>0.9</priority>
</url>
...
</urlset>
The URL for each post is created using the get_absolute_url()
method. The lastmod
attribute corresponds to the updated
field of the post, as defined in the sitemap. And attributes changefreq
and priority
are taken from PostSitemap
class. The domain used to create the URL is example.com
. It comes from the Site
object, which is stored in the database. This object is created by default when you synchronize the site structure with the database. Open https://127.0.0.1:8000/admin/sites/site/ in your browser. The following will be displayed:
This screenshot shows the view to display a list of the site structure. Here you can assign a domain or host to be used by the site structure and the applications that work with it. To generate the URL in a local environment, you need to change the domain name to
localhost:8000
as shown in the previous screenshot and save:The URLs displayed in the feed will now be built using the hostname. You will need to use the domain name when deploying the site.