You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

views.py 3.4KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import datetime
  2. from calendar import timegm
  3. from functools import wraps
  4. from django.contrib.sites.shortcuts import get_current_site
  5. from django.core.paginator import EmptyPage, PageNotAnInteger
  6. from django.http import Http404
  7. from django.template.response import TemplateResponse
  8. from django.urls import reverse
  9. from django.utils.http import http_date
  10. def x_robots_tag(func):
  11. @wraps(func)
  12. def inner(request, *args, **kwargs):
  13. response = func(request, *args, **kwargs)
  14. response['X-Robots-Tag'] = 'noindex, noodp, noarchive'
  15. return response
  16. return inner
  17. @x_robots_tag
  18. def index(request, sitemaps,
  19. template_name='sitemap_index.xml', content_type='application/xml',
  20. sitemap_url_name='django.contrib.sitemaps.views.sitemap'):
  21. req_protocol = request.scheme
  22. req_site = get_current_site(request)
  23. sites = [] # all sections' sitemap URLs
  24. for section, site in sitemaps.items():
  25. # For each section label, add links of all pages of its sitemap
  26. # (usually generated by the `sitemap` view).
  27. if callable(site):
  28. site = site()
  29. protocol = req_protocol if site.protocol is None else site.protocol
  30. sitemap_url = reverse(sitemap_url_name, kwargs={'section': section})
  31. absolute_url = '%s://%s%s' % (protocol, req_site.domain, sitemap_url)
  32. sites.append(absolute_url)
  33. # Add links to all pages of the sitemap.
  34. for page in range(2, site.paginator.num_pages + 1):
  35. sites.append('%s?p=%s' % (absolute_url, page))
  36. return TemplateResponse(request, template_name, {'sitemaps': sites},
  37. content_type=content_type)
  38. @x_robots_tag
  39. def sitemap(request, sitemaps, section=None,
  40. template_name='sitemap.xml', content_type='application/xml'):
  41. req_protocol = request.scheme
  42. req_site = get_current_site(request)
  43. if section is not None:
  44. if section not in sitemaps:
  45. raise Http404("No sitemap available for section: %r" % section)
  46. maps = [sitemaps[section]]
  47. else:
  48. maps = sitemaps.values()
  49. page = request.GET.get("p", 1)
  50. lastmod = None
  51. all_sites_lastmod = True
  52. urls = []
  53. for site in maps:
  54. try:
  55. if callable(site):
  56. site = site()
  57. urls.extend(site.get_urls(page=page, site=req_site,
  58. protocol=req_protocol))
  59. if all_sites_lastmod:
  60. site_lastmod = getattr(site, 'latest_lastmod', None)
  61. if site_lastmod is not None:
  62. site_lastmod = (
  63. site_lastmod.utctimetuple() if isinstance(site_lastmod, datetime.datetime)
  64. else site_lastmod.timetuple()
  65. )
  66. lastmod = site_lastmod if lastmod is None else max(lastmod, site_lastmod)
  67. else:
  68. all_sites_lastmod = False
  69. except EmptyPage:
  70. raise Http404("Page %s empty" % page)
  71. except PageNotAnInteger:
  72. raise Http404("No page '%s'" % page)
  73. response = TemplateResponse(request, template_name, {'urlset': urls},
  74. content_type=content_type)
  75. if all_sites_lastmod and lastmod is not None:
  76. # if lastmod is defined for all sites, set header so as
  77. # ConditionalGetMiddleware is able to send 304 NOT MODIFIED
  78. response['Last-Modified'] = http_date(timegm(lastmod))
  79. return response