Fixed #23403 -- Fixed crash in contrib.sitemaps if lastmod returned a date rather than datetime.

Thanks igorcc for the report.
This commit is contained in:
Tim Graham 2014-09-09 13:34:40 -04:00
parent c5b4145fca
commit 66580fe97c
4 changed files with 39 additions and 2 deletions

View File

@ -82,6 +82,21 @@ class HTTPSitemapTests(SitemapTestsBase):
response = self.client.get('/lastmod/sitemap.xml') response = self.client.get('/lastmod/sitemap.xml')
self.assertEqual(response['Last-Modified'], 'Wed, 13 Mar 2013 10:00:00 GMT') self.assertEqual(response['Last-Modified'], 'Wed, 13 Mar 2013 10:00:00 GMT')
def test_sitemap_last_modified_date(self):
"""
The Last-Modified header should be support dates (without time).
"""
response = self.client.get('/lastmod/date-sitemap.xml')
self.assertEqual(response['Last-Modified'], 'Wed, 13 Mar 2013 00:00:00 GMT')
def test_sitemap_last_modified_tz(self):
"""
The Last-Modified header should be converted from timezone aware dates
to GMT.
"""
response = self.client.get('/lastmod/tz-sitemap.xml')
self.assertEqual(response['Last-Modified'], 'Wed, 13 Mar 2013 15:00:00 GMT')
def test_sitemap_last_modified_missing(self): def test_sitemap_last_modified_missing(self):
"Tests that Last-Modified header is missing when sitemap has no lastmod" "Tests that Last-Modified header is missing when sitemap has no lastmod"
response = self.client.get('/generic/sitemap.xml') response = self.client.get('/generic/sitemap.xml')

View File

@ -1,8 +1,9 @@
from datetime import datetime from datetime import date, datetime
from django.conf.urls import url from django.conf.urls import url
from django.conf.urls.i18n import i18n_patterns from django.conf.urls.i18n import i18n_patterns
from django.contrib.sitemaps import Sitemap, GenericSitemap, FlatPageSitemap, views from django.contrib.sitemaps import Sitemap, GenericSitemap, FlatPageSitemap, views
from django.http import HttpResponse from django.http import HttpResponse
from django.utils import timezone
from django.views.decorators.cache import cache_page from django.views.decorators.cache import cache_page
from django.contrib.sitemaps.tests.base import I18nTestModel, TestModel from django.contrib.sitemaps.tests.base import I18nTestModel, TestModel
@ -53,6 +54,14 @@ class FixedLastmodMixedSitemap(Sitemap):
return [o1, o2] return [o1, o2]
class DateSiteMap(SimpleSitemap):
lastmod = date(2013, 3, 13)
class TimezoneSiteMap(SimpleSitemap):
lastmod = datetime(2013, 3, 13, 10, 0, 0, tzinfo=timezone.get_fixed_timezone(-300))
def testmodelview(request, id): def testmodelview(request, id):
return HttpResponse() return HttpResponse()
@ -99,6 +108,10 @@ urlpatterns = [
url(r'^empty/sitemap\.xml$', views.sitemap, {'sitemaps': empty_sitemaps}), url(r'^empty/sitemap\.xml$', views.sitemap, {'sitemaps': empty_sitemaps}),
url(r'^lastmod/sitemap\.xml$', views.sitemap, {'sitemaps': fixed_lastmod_sitemaps}), url(r'^lastmod/sitemap\.xml$', views.sitemap, {'sitemaps': fixed_lastmod_sitemaps}),
url(r'^lastmod-mixed/sitemap\.xml$', views.sitemap, {'sitemaps': fixed_lastmod__mixed_sitemaps}), url(r'^lastmod-mixed/sitemap\.xml$', views.sitemap, {'sitemaps': fixed_lastmod__mixed_sitemaps}),
url(r'^lastmod/date-sitemap.xml$', views.sitemap,
{'sitemaps': {'date-sitemap': DateSiteMap}}),
url(r'^lastmod/tz-sitemap.xml$', views.sitemap,
{'sitemaps': {'tz-sitemap': TimezoneSiteMap}}),
url(r'^generic/sitemap\.xml$', views.sitemap, {'sitemaps': generic_sitemaps}), url(r'^generic/sitemap\.xml$', views.sitemap, {'sitemaps': generic_sitemaps}),
url(r'^flatpages/sitemap\.xml$', views.sitemap, {'sitemaps': flatpage_sitemaps}), url(r'^flatpages/sitemap\.xml$', views.sitemap, {'sitemaps': flatpage_sitemaps}),
url(r'^cached/index\.xml$', cache_page(1)(views.index), url(r'^cached/index\.xml$', cache_page(1)(views.index),

View File

@ -1,4 +1,5 @@
from calendar import timegm from calendar import timegm
import datetime
from functools import wraps from functools import wraps
from django.contrib.sites.shortcuts import get_current_site from django.contrib.sites.shortcuts import get_current_site
@ -74,6 +75,11 @@ def sitemap(request, sitemaps, section=None,
if hasattr(site, 'latest_lastmod'): if hasattr(site, 'latest_lastmod'):
# if latest_lastmod is defined for site, set header so as # if latest_lastmod is defined for site, set header so as
# ConditionalGetMiddleware is able to send 304 NOT MODIFIED # ConditionalGetMiddleware is able to send 304 NOT MODIFIED
lastmod = site.latest_lastmod
response['Last-Modified'] = http_date( response['Last-Modified'] = http_date(
timegm(site.latest_lastmod.utctimetuple())) timegm(
lastmod.utctimetuple() if isinstance(lastmod, datetime.datetime)
else lastmod.timetuple()
)
)
return response return response

View File

@ -40,3 +40,6 @@ Bugfixes
* Empty ``index_together`` or ``unique_together`` model options no longer * Empty ``index_together`` or ``unique_together`` model options no longer
results in infinite migrations (:ticket:`23452`). results in infinite migrations (:ticket:`23452`).
* Fixed crash in ``contrib.sitemaps`` if ``lastmod`` returned a ``date`` rather
than a ``datetime`` (:ticket:`23403`).