Fixed #16906 -- Format datetimes with str/unicode instead of strftime where possible: it's faster and it works for all dates.
Also ensured that datetime_safe is used wherever strftime is called on dates/datetimes that may be before 1900. git-svn-id: http://code.djangoproject.com/svn/django/trunk@16978 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
b7845768cb
commit
06d9b82a27
|
@ -281,9 +281,9 @@ class DateFieldListFilter(FieldListFilter):
|
||||||
|
|
||||||
today = datetime.date.today()
|
today = datetime.date.today()
|
||||||
one_week_ago = today - datetime.timedelta(days=7)
|
one_week_ago = today - datetime.timedelta(days=7)
|
||||||
today_str = (isinstance(self.field, models.DateTimeField)
|
today_str = str(today)
|
||||||
and today.strftime('%Y-%m-%d 23:59:59')
|
if isinstance(self.field, models.DateTimeField):
|
||||||
or today.strftime('%Y-%m-%d'))
|
today_str += ' 23:59:59'
|
||||||
|
|
||||||
self.lookup_kwarg_year = '%s__year' % self.field_path
|
self.lookup_kwarg_year = '%s__year' % self.field_path
|
||||||
self.lookup_kwarg_month = '%s__month' % self.field_path
|
self.lookup_kwarg_month = '%s__month' % self.field_path
|
||||||
|
@ -299,7 +299,7 @@ class DateFieldListFilter(FieldListFilter):
|
||||||
self.lookup_kwarg_day: str(today.day),
|
self.lookup_kwarg_day: str(today.day),
|
||||||
}),
|
}),
|
||||||
(_('Past 7 days'), {
|
(_('Past 7 days'), {
|
||||||
self.lookup_kwarg_past_7_days_gte: one_week_ago.strftime('%Y-%m-%d'),
|
self.lookup_kwarg_past_7_days_gte: str(one_week_ago),
|
||||||
self.lookup_kwarg_past_7_days_lte: today_str,
|
self.lookup_kwarg_past_7_days_lte: today_str,
|
||||||
}),
|
}),
|
||||||
(_('This month'), {
|
(_('This month'), {
|
||||||
|
|
|
@ -52,14 +52,13 @@ class PasswordResetTokenGenerator(object):
|
||||||
# invalid as soon as it is used.
|
# invalid as soon as it is used.
|
||||||
# We limit the hash to 20 chars to keep URL short
|
# We limit the hash to 20 chars to keep URL short
|
||||||
key_salt = "django.contrib.auth.tokens.PasswordResetTokenGenerator"
|
key_salt = "django.contrib.auth.tokens.PasswordResetTokenGenerator"
|
||||||
value = unicode(user.id) + \
|
value = (unicode(user.id) + user.password +
|
||||||
user.password + user.last_login.strftime('%Y-%m-%d %H:%M:%S') + \
|
unicode(user.last_login) + unicode(timestamp))
|
||||||
unicode(timestamp)
|
|
||||||
hash = salted_hmac(key_salt, value).hexdigest()[::2]
|
hash = salted_hmac(key_salt, value).hexdigest()[::2]
|
||||||
return "%s-%s" % (ts_b36, hash)
|
return "%s-%s" % (ts_b36, hash)
|
||||||
|
|
||||||
def _num_days(self, dt):
|
def _num_days(self, dt):
|
||||||
return (dt - date(2001,1,1)).days
|
return (dt - date(2001, 1, 1)).days
|
||||||
|
|
||||||
def _today(self):
|
def _today(self):
|
||||||
# Used for mocking in tests
|
# Used for mocking in tests
|
||||||
|
|
|
@ -67,7 +67,7 @@ class SitemapTests(TestCase):
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
<url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
|
<url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
|
||||||
</urlset>
|
</urlset>
|
||||||
""" % (self.base_url, date.today().strftime('%Y-%m-%d')))
|
""" % (self.base_url, date.today()))
|
||||||
|
|
||||||
def test_simple_custom_sitemap(self):
|
def test_simple_custom_sitemap(self):
|
||||||
"A simple sitemap can be rendered with a custom template"
|
"A simple sitemap can be rendered with a custom template"
|
||||||
|
@ -79,7 +79,7 @@ class SitemapTests(TestCase):
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
<url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
|
<url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
|
||||||
</urlset>
|
</urlset>
|
||||||
""" % (self.base_url, date.today().strftime('%Y-%m-%d')))
|
""" % (self.base_url, date.today()))
|
||||||
|
|
||||||
@skipUnless(settings.USE_I18N, "Internationalization is not enabled")
|
@skipUnless(settings.USE_I18N, "Internationalization is not enabled")
|
||||||
def test_localized_priority(self):
|
def test_localized_priority(self):
|
||||||
|
@ -93,7 +93,7 @@ class SitemapTests(TestCase):
|
||||||
# haven't been rendered in localized format
|
# haven't been rendered in localized format
|
||||||
response = self.client.get('/simple/sitemap.xml')
|
response = self.client.get('/simple/sitemap.xml')
|
||||||
self.assertContains(response, '<priority>0.5</priority>')
|
self.assertContains(response, '<priority>0.5</priority>')
|
||||||
self.assertContains(response, '<lastmod>%s</lastmod>' % date.today().strftime('%Y-%m-%d'))
|
self.assertContains(response, '<lastmod>%s</lastmod>' % date.today())
|
||||||
deactivate()
|
deactivate()
|
||||||
|
|
||||||
def test_generic_sitemap(self):
|
def test_generic_sitemap(self):
|
||||||
|
@ -152,7 +152,7 @@ class SitemapTests(TestCase):
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
<url><loc>http://testserver/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
|
<url><loc>http://testserver/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
|
||||||
</urlset>
|
</urlset>
|
||||||
""" % date.today().strftime('%Y-%m-%d'))
|
""" % date.today())
|
||||||
|
|
||||||
@skipUnless("django.contrib.sites" in settings.INSTALLED_APPS, "django.contrib.sites app not installed.")
|
@skipUnless("django.contrib.sites" in settings.INSTALLED_APPS, "django.contrib.sites app not installed.")
|
||||||
def test_sitemap_get_urls_no_site_1(self):
|
def test_sitemap_get_urls_no_site_1(self):
|
||||||
|
|
|
@ -9,7 +9,6 @@ from django.conf import settings
|
||||||
from django.db import DEFAULT_DB_ALIAS
|
from django.db import DEFAULT_DB_ALIAS
|
||||||
from django.db.backends import util
|
from django.db.backends import util
|
||||||
from django.db.transaction import TransactionManagementError
|
from django.db.transaction import TransactionManagementError
|
||||||
from django.utils import datetime_safe
|
|
||||||
from django.utils.importlib import import_module
|
from django.utils.importlib import import_module
|
||||||
|
|
||||||
|
|
||||||
|
@ -718,7 +717,7 @@ class BaseDatabaseOperations(object):
|
||||||
"""
|
"""
|
||||||
if value is None:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
return datetime_safe.new_date(value).strftime('%Y-%m-%d')
|
return unicode(value)
|
||||||
|
|
||||||
def value_to_db_datetime(self, value):
|
def value_to_db_datetime(self, value):
|
||||||
"""
|
"""
|
||||||
|
@ -731,7 +730,7 @@ class BaseDatabaseOperations(object):
|
||||||
|
|
||||||
def value_to_db_time(self, value):
|
def value_to_db_time(self, value):
|
||||||
"""
|
"""
|
||||||
Transform a datetime value to an object compatible with what is expected
|
Transform a time value to an object compatible with what is expected
|
||||||
by the backend driver for time columns.
|
by the backend driver for time columns.
|
||||||
"""
|
"""
|
||||||
if value is None:
|
if value is None:
|
||||||
|
|
|
@ -320,14 +320,9 @@ def _sqlite_format_dtdelta(dt, conn, days, secs, usecs):
|
||||||
dt = dt - delta
|
dt = dt - delta
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
return None
|
return None
|
||||||
|
# typecast_timestamp returns a date or a datetime without timezone.
|
||||||
if isinstance(dt, datetime.datetime):
|
# It will be formatted as "%Y-%m-%d" or "%Y-%m-%d %H:%M:%S[.%f]"
|
||||||
rv = dt.strftime("%Y-%m-%d %H:%M:%S")
|
return str(dt)
|
||||||
if dt.microsecond:
|
|
||||||
rv = "%s.%0.6d" % (rv, dt.microsecond)
|
|
||||||
else:
|
|
||||||
rv = dt.strftime("%Y-%m-%d")
|
|
||||||
return rv
|
|
||||||
|
|
||||||
def _sqlite_regexp(re_pattern, re_string):
|
def _sqlite_regexp(re_pattern, re_string):
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -16,7 +16,6 @@ from django.utils.functional import curry
|
||||||
from django.utils.text import capfirst
|
from django.utils.text import capfirst
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.utils.encoding import smart_unicode, force_unicode, smart_str
|
from django.utils.encoding import smart_unicode, force_unicode, smart_str
|
||||||
from django.utils import datetime_safe
|
|
||||||
from django.utils.ipv6 import clean_ipv6_address
|
from django.utils.ipv6 import clean_ipv6_address
|
||||||
|
|
||||||
class NOT_PROVIDED:
|
class NOT_PROVIDED:
|
||||||
|
@ -725,7 +724,7 @@ class DateField(Field):
|
||||||
if val is None:
|
if val is None:
|
||||||
data = ''
|
data = ''
|
||||||
else:
|
else:
|
||||||
data = datetime_safe.new_date(val).strftime("%Y-%m-%d")
|
data = str(val)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def formfield(self, **kwargs):
|
def formfield(self, **kwargs):
|
||||||
|
@ -803,8 +802,7 @@ class DateTimeField(DateField):
|
||||||
if val is None:
|
if val is None:
|
||||||
data = ''
|
data = ''
|
||||||
else:
|
else:
|
||||||
d = datetime_safe.new_datetime(val)
|
data = str(val.replace(microsecond=0, tzinfo=None))
|
||||||
data = d.strftime('%Y-%m-%d %H:%M:%S')
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def formfield(self, **kwargs):
|
def formfield(self, **kwargs):
|
||||||
|
@ -1234,7 +1232,7 @@ class TimeField(Field):
|
||||||
if val is None:
|
if val is None:
|
||||||
data = ''
|
data = ''
|
||||||
else:
|
else:
|
||||||
data = val.strftime("%H:%M:%S")
|
data = str(val.replace(microsecond=0))
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def formfield(self, **kwargs):
|
def formfield(self, **kwargs):
|
||||||
|
|
|
@ -188,8 +188,8 @@ class ListFiltersTests(TestCase):
|
||||||
self.assertEqual(choice['query_string'], '?date_registered__year=%s'
|
self.assertEqual(choice['query_string'], '?date_registered__year=%s'
|
||||||
% (self.today.year))
|
% (self.today.year))
|
||||||
|
|
||||||
request = self.request_factory.get('/', {'date_registered__gte': self.one_week_ago.strftime('%Y-%m-%d'),
|
request = self.request_factory.get('/', {'date_registered__gte': str(self.one_week_ago),
|
||||||
'date_registered__lte': self.today.strftime('%Y-%m-%d')})
|
'date_registered__lte': str(self.today)})
|
||||||
changelist = self.get_changelist(request, Book, modeladmin)
|
changelist = self.get_changelist(request, Book, modeladmin)
|
||||||
|
|
||||||
# Make sure the correct queryset is returned
|
# Make sure the correct queryset is returned
|
||||||
|
@ -203,7 +203,7 @@ class ListFiltersTests(TestCase):
|
||||||
self.assertEqual(choice['selected'], True)
|
self.assertEqual(choice['selected'], True)
|
||||||
self.assertEqual(choice['query_string'], '?date_registered__gte=%s'
|
self.assertEqual(choice['query_string'], '?date_registered__gte=%s'
|
||||||
'&date_registered__lte=%s'
|
'&date_registered__lte=%s'
|
||||||
% (self.one_week_ago.strftime('%Y-%m-%d'), self.today.strftime('%Y-%m-%d')))
|
% (str(self.one_week_ago), str(self.today)))
|
||||||
|
|
||||||
def test_allvaluesfieldlistfilter(self):
|
def test_allvaluesfieldlistfilter(self):
|
||||||
modeladmin = BookAdmin(Book, site)
|
modeladmin = BookAdmin(Book, site)
|
||||||
|
|
Loading…
Reference in New Issue