It is not possible to access HttpRequest
object from Sitemap
class. Probably the easiest way is to create your own view(s) for the sitemap(s), do what you need to do with HttpRequest
and call Django internal view to do the final rendering of XML.
Setup your sitemap URLs as Django docs says (https://docs.djangoproject.com/en/dev/ref/contrib/sitemaps/#initialization), but use your own view(s).
urls.py
:
from my_app.sitemap_views import custom_sitemap_index, custom_sitemap_section
sitemaps = {
"foo": FooSitemap,
"bar": BarSitemap,
}
urlpatterns = [
url(
r"^sitemap\.xml$",
custom_sitemap_index,
{"sitemaps": sitemaps},
name="sitemap_index",
),
url(
r"^sitemap-(?P<section>.+)\.xml$",
custom_sitemap_section,
{"sitemaps": sitemaps},
name="sitemaps",
),
# ...
]
Your custom sitemap views are standard Django views: you can access HttpRequest
, database, cache...
sitemap_views.py
:
import copy
from django.contrib.sitemaps import views as django_sitemaps_views
from django.contrib.sitemaps.views import x_robots_tag
@x_robots_tag
def custom_sitemap_index(
request,
sitemaps,
template_name="sitemap_index.xml",
content_type="application/xml",
sitemap_url_name="django.contrib.sitemaps.views.sitemap",
):
print("You can access request here.", request)
return django_sitemaps_views.index(
request, template_name, content_type, sitemaps, sitemap_url_name
)
@x_robots_tag
def custom_sitemap_section(
request,
sitemaps,
section=None,
template_name="sitemap.xml",
content_type="application/xml",
):
tag_id = int(request.GET.get("tagid"))
# We do not want to modify global variable "sitemaps"!
# Otherwise sitemap instances would be shared across requests (tag_id should be dynamic).
sitemaps_copy = copy.deepcopy(sitemaps)
for section, site in sitemaps_copy.items():
if callable(site):
sitemaps_copy[section] = site(tag_id=tag_id)
return django_sitemaps_views.sitemap(
request, sitemaps_copy, section, template_name, content_type
)
sitemap.py
:
from django.contrib.sitemaps import Sitemap
class FooSitemap(Sitemap):
def __init__(self, tag_id: int):
self.tag_id = tag_id
super().__init__()
def items(self):
return (
Articles.objects.filter(tagid=1399)
.filter(tag_id=self.tag_id)
.order_by("-publisheddate")
)
class BarSitemap(Sitemap):
pass
# ...
# ...