Package: django-sitemap-generate
Django Sitemap GenerateBackground sitemap generation for Django.Use caseAlmost every content site has a sitemap. Django provides an application serving
sitemap views, and it's OK if your website is small. If you have complicate
logic in sitemap generation or if you have millions of items in sitemap - you'll
have a massive load spikes when Google and another search engines come with
thousands of there indexer bots. These bots will request same sitemap pages in
parallel and those requests couldn't be cached because of large index interval
and small hit rate.The solution is to re-generate sitemap files periodically, once per day and not
once per search engine indexer. These files could be served as static files
which will not affect backend performance at all.PrerequisitesThese project uses index sitemap view and per-model sitemap views to generate
sitemap xml files. To provide it you will need following.Adddjango.contrib.sitemapsto installed appsINSTALLED_APPS.append('django.contrib.sitemaps')Configure at least one sitemapfromdjango.contrib.sitemapsimportSitemapfromtestproject.testappimportmodelsclassVideoSitemap(Sitemap):name='video'changefreq='daily'limit=50000defitems(self):returnmodels.Video.objects.order_by('id')Note thatchangefreqparameter is a hint for search engine indexer, it
does not affect sitemap files generation period.Configure sitemap servingfromdjango.contrib.sitemapsimportviewsfromdjango.urlsimportpathfromtestproject.testapp.sitemapsimportVideoSitemap,ArticleSitemapsitemaps={VideoSitemap.name:VideoSitemap,ArticleSitemap.name:ArticleSitemap}urlpatterns=[path('sitemap.xml',views.index,{'sitemaps':sitemaps},name='sitemap-index'),path('sitemap-<section>.xml',views.sitemap,{'sitemaps':sitemaps},name='django.contrib.sitemaps.views.sitemap'),]Now your website supports sitemap views.Installationpipinstalldjango-sitemap-generateWorking example is intestproject.testapp.Addsitemap_generateapplication to installed apps in django settings:INSTALLED_APPS.append('sitemap_generate')Add a reference to sitemap mapping to django settings:SITEMAP_MAPPING='testproject.testapp.urls.sitemaps'Specify name of the sitemap index url. If you haveurlpatternslike
example above, you can write:SITEMAP_INDEX_NAME='sitemap-index'default:'sitemap-index'Specify name of theview.sitemapview. If you haveurlpatternslike
example above, you can write:SITEMAPS_VIEW_NAME='django.contrib.sitemaps.views.sitemap'default:'django.contrib.sitemaps.views.sitemap'Set media path to store sitemaps underSITEMAP_MEDIA_PATH='sitemaps'default:'sitemaps'Also you may need to setup forwarded protocol handling in django settings:SECURE_PROXY_SSL_HEADER=('HTTP_X_FORWARDED_PROTO','https')Note that django paginates sitemap withpquery parameter, but
corresponding sitemap files are namedsitemap-video.xml,sitemap-video-2.xmland so on. You'll need to configure some "rewrites".Optional. Change storage for generated sitemapsSITEMAP_STORAGE=custom_storagedefault:django.core.files.storage.default_storageUsageWhen you request sitemap over http, django substitutes website domain name from
request to links in sitemap xml. In background, you'll need some environment
variables. By defaults link are generated forlocalhostover HTTPS.export\SITEMAP_PROTO=https\SITEMAP_HOST=github.com\SITEMAP_PORT=443# generate all sitemapspythonmanage.pygenerate_sitemap# generate sitemap for single modelpythonmanage.pygenerate_sitemapvideoYou may run sitemap generation from crontab:0 0 * * * python manage.py generate_sitemapYou may run sitemap generation from celery:@celery.taskdefgenerate_sitemap():generator=SitemapGenerator()# Uses django settings by defaultgenerator.generate()And you will need to configure xml files static responses, i.e. in nginx:location ~* /sitemaps/(?<fn>sitemap(-(article|video)).xml {
    try_files /media/sitemaps/$fn$arg_p.xml @backend;
}

location /media/ {
    alias /app/media/;
}

location @backend {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    set $app http://app:8000;
    proxy_pass $app;
}