1
0
mirror of https://github.com/django/django.git synced 2025-07-04 01:39:20 +00:00

newforms-admin: Merged from trunk up to [7947].

git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@7948 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Brian Rosner 2008-07-18 15:47:10 +00:00
parent 9188013889
commit b2231a28e8
15 changed files with 173 additions and 30 deletions

View File

@ -8,6 +8,7 @@ from django.utils.translation import get_date_formats
from django.utils.encoding import force_unicode
from django.utils.safestring import mark_safe
from django.views.generic import date_based
from django.utils import datetime_safe
class CalendarPlugin(DatabrowsePlugin):
def __init__(self, field_names=None):
@ -33,12 +34,13 @@ class CalendarPlugin(DatabrowsePlugin):
def urls(self, plugin_name, easy_instance_field):
if isinstance(easy_instance_field.field, models.DateField):
d = easy_instance_field.raw_value
return [mark_safe(u'%s%s/%s/%s/%s/%s/' % (
easy_instance_field.model.url(),
plugin_name, easy_instance_field.field.name,
easy_instance_field.raw_value.year,
easy_instance_field.raw_value.strftime('%b').lower(),
easy_instance_field.raw_value.day))]
d.year,
datetime_safe.new_date(d).strftime('%b').lower(),
d.day))]
def model_view(self, request, model_databrowse, url):
self.model, self.site = model_databrowse.model, model_databrowse.site

View File

@ -8,6 +8,7 @@ except ImportError:
from StringIO import StringIO
from django.db import models
from django.utils.encoding import smart_str, smart_unicode
from django.utils import datetime_safe
class SerializationError(Exception):
"""Something bad happened during serialization."""
@ -59,7 +60,8 @@ class Serializer(object):
Convert a field's value to a string.
"""
if isinstance(field, models.DateTimeField):
value = getattr(obj, field.name).strftime("%Y-%m-%d %H:%M:%S")
d = datetime_safe.new_datetime(getattr(obj, field.name))
value = d.strftime("%Y-%m-%d %H:%M:%S")
else:
value = field.flatten_data(follow=None, obj=obj).get(field.name, "")
return smart_unicode(value)

View File

@ -6,6 +6,7 @@ import datetime
from django.utils import simplejson
from django.core.serializers.python import Serializer as PythonSerializer
from django.core.serializers.python import Deserializer as PythonDeserializer
from django.utils import datetime_safe
try:
from cStringIO import StringIO
except ImportError:
@ -51,9 +52,11 @@ class DjangoJSONEncoder(simplejson.JSONEncoder):
def default(self, o):
if isinstance(o, datetime.datetime):
return o.strftime("%s %s" % (self.DATE_FORMAT, self.TIME_FORMAT))
d = datetime_safe.new_datetime(o)
return d.strftime("%s %s" % (self.DATE_FORMAT, self.TIME_FORMAT))
elif isinstance(o, datetime.date):
return o.strftime(self.DATE_FORMAT)
d = datetime_safe.new_date(o)
return d.strftime(self.DATE_FORMAT)
elif isinstance(o, datetime.time):
return o.strftime(self.TIME_FORMAT)
elif isinstance(o, decimal.Decimal):

View File

@ -141,10 +141,6 @@ def _isValidDate(date_string):
# Could use time.strptime here and catch errors, but datetime.date below
# produces much friendlier error messages.
year, month, day = map(int, date_string.split('-'))
# This check is needed because strftime is used when saving the date
# value to the database, and strftime requires that the year be >=1900.
if year < 1900:
raise ValidationError, _('Year must be 1900 or later.')
try:
date(year, month, day)
except ValueError, e:

View File

@ -13,7 +13,6 @@ DATA_TYPES = {
'FileField': 'varchar(%(max_length)s)',
'FilePathField': 'varchar(%(max_length)s)',
'FloatField': 'double precision',
'ImageField': 'varchar(%(max_length)s)',
'IntegerField': 'integer',
'IPAddressField': 'char(15)',
'NullBooleanField': 'bool',

View File

@ -13,7 +13,6 @@ DATA_TYPES = {
'FileField': 'varchar(%(max_length)s)',
'FilePathField': 'varchar(%(max_length)s)',
'FloatField': 'double precision',
'ImageField': 'varchar(%(max_length)s)',
'IntegerField': 'integer',
'IPAddressField': 'char(15)',
'NullBooleanField': 'bool',

View File

@ -20,7 +20,6 @@ DATA_TYPES = {
'FileField': 'NVARCHAR2(%(max_length)s)',
'FilePathField': 'NVARCHAR2(%(max_length)s)',
'FloatField': 'DOUBLE PRECISION',
'ImageField': 'NVARCHAR2(%(max_length)s)',
'IntegerField': 'NUMBER(11)',
'IPAddressField': 'VARCHAR2(15)',
'NullBooleanField': 'NUMBER(1) CHECK ((%(qn_column)s IN (0,1)) OR (%(qn_column)s IS NULL))',

View File

@ -13,7 +13,6 @@ DATA_TYPES = {
'FileField': 'varchar(%(max_length)s)',
'FilePathField': 'varchar(%(max_length)s)',
'FloatField': 'double precision',
'ImageField': 'varchar(%(max_length)s)',
'IntegerField': 'integer',
'IPAddressField': 'inet',
'NullBooleanField': 'boolean',

View File

@ -12,7 +12,6 @@ DATA_TYPES = {
'FileField': 'varchar(%(max_length)s)',
'FilePathField': 'varchar(%(max_length)s)',
'FloatField': 'real',
'ImageField': 'varchar(%(max_length)s)',
'IntegerField': 'integer',
'IPAddressField': 'char(15)',
'NullBooleanField': 'bool',

View File

@ -23,6 +23,7 @@ from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy, ugettext as _
from django.utils.encoding import smart_unicode, force_unicode, smart_str
from django.utils.maxlength import LegacyMaxlength
from django.utils import datetime_safe
class NOT_PROVIDED:
pass
@ -542,7 +543,7 @@ class DateField(Field):
if lookup_type in ('range', 'in'):
value = [smart_unicode(v) for v in value]
elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte') and hasattr(value, 'strftime'):
value = value.strftime('%Y-%m-%d')
value = datetime_safe.new_date(value).strftime('%Y-%m-%d')
else:
value = smart_unicode(value)
return Field.get_db_prep_lookup(self, lookup_type, value)
@ -574,7 +575,7 @@ class DateField(Field):
# Casts dates into string format for entry into database.
if value is not None:
try:
value = value.strftime('%Y-%m-%d')
value = datetime_safe.new_date(value).strftime('%Y-%m-%d')
except AttributeError:
# If value is already a string it won't have a strftime method,
# so we'll just let it pass through.
@ -586,7 +587,11 @@ class DateField(Field):
def flatten_data(self, follow, obj=None):
val = self._get_val_from_obj(obj)
return {self.attname: (val is not None and val.strftime("%Y-%m-%d") or '')}
if val is None:
data = ''
else:
data = datetime_safe.new_date(val).strftime("%Y-%m-%d")
return {self.attname: data}
def formfield(self, **kwargs):
defaults = {'form_class': forms.DateField}
@ -653,8 +658,13 @@ class DateTimeField(DateField):
def flatten_data(self,follow, obj = None):
val = self._get_val_from_obj(obj)
date_field, time_field = self.get_manipulator_field_names('')
return {date_field: (val is not None and val.strftime("%Y-%m-%d") or ''),
time_field: (val is not None and val.strftime("%H:%M:%S") or '')}
if val is None:
date_data = time_data = ''
else:
d = datetime_safe.new_datetime(val)
date_data = d.strftime('%Y-%m-%d')
time_data = d.strftime('%H:%M:%S')
return {date_field: date_data, time_field: time_data}
def formfield(self, **kwargs):
defaults = {'form_class': forms.DateTimeField}
@ -917,9 +927,6 @@ class ImageField(FileField):
if not self.height_field:
setattr(cls, 'get_%s_height' % self.name, curry(cls._get_FIELD_height, field=self))
def get_internal_type(self):
return "ImageField"
def save_file(self, new_data, new_object, original_object, change, rel, save=True):
FileField.save_file(self, new_data, new_object, original_object, change, rel, save)
# If the image has height and/or width field(s) and they haven't

View File

@ -9,6 +9,7 @@ from django.utils.datastructures import DotExpandedDict
from django.utils.text import capfirst
from django.utils.encoding import smart_str
from django.utils.translation import ugettext as _
from django.utils import datetime_safe
def add_manipulators(sender):
cls = sender
@ -327,5 +328,6 @@ def manipulator_validator_unique_for_date(from_field, date_field, opts, lookup_t
pass
else:
format_string = (lookup_type == 'date') and '%B %d, %Y' or '%B %Y'
date_val = datetime_safe.new_datetime(date_val)
raise validators.ValidationError, "Please enter a different %s. The one you entered is already being used for %s." % \
(from_field.verbose_name, date_val.strftime(format_string))

View File

@ -15,6 +15,7 @@ from django.utils.html import escape, conditional_escape
from django.utils.translation import ugettext
from django.utils.encoding import StrAndUnicode, force_unicode
from django.utils.safestring import mark_safe
from django.utils import datetime_safe
from util import flatatt
from urlparse import urljoin
@ -296,6 +297,7 @@ class DateTimeInput(Input):
if value is None:
value = ''
elif hasattr(value, 'strftime'):
value = datetime_safe.new_datetime(value)
value = value.strftime(self.format)
return super(DateTimeInput, self).render(name, value, attrs)

View File

@ -0,0 +1,89 @@
# Python's datetime strftime doesn't handle dates before 1900.
# These classes override date and datetime to support the formatting of a date
# through its full "proleptic Gregorian" date range.
#
# Based on code submitted to comp.lang.python by Andrew Dalke
#
# >>> datetime_safe.date(1850, 8, 2).strftime("%Y/%M/%d was a %A")
# '1850/08/02 was a Friday'
from datetime import date as real_date, datetime as real_datetime
import re
import time
class date(real_date):
def strftime(self, fmt):
return strftime(self, fmt)
class datetime(real_datetime):
def strftime(self, fmt):
return strftime(self, fmt)
def combine(self, date, time):
return datetime(date.year, date.month, date.day, time.hour, time.minute, time.microsecond, time.tzinfo)
def date(self):
return date(self.year, self.month, self.day)
def new_date(d):
"Generate a safe date from a datetime.date object."
return date(d.year, d.month, d.day)
def new_datetime(d):
"""
Generate a safe datetime from a datetime.date or datetime.datetime object.
"""
kw = [d.year, d.month, d.day]
if isinstance(d, real_datetime):
kw.extend([d.hour, d.minute, d.second, d.microsecond, d.tzinfo])
return datetime(*kw)
# This library does not support strftime's "%s" or "%y" format strings.
# Allowed if there's an even number of "%"s because they are escaped.
_illegal_formatting = re.compile(r"((^|[^%])(%%)*%[sy])")
def _findall(text, substr):
# Also finds overlaps
sites = []
i = 0
while 1:
j = text.find(substr, i)
if j == -1:
break
sites.append(j)
i=j+1
return sites
def strftime(dt, fmt):
if dt.year >= 1900:
return super(type(dt), dt).strftime(fmt)
illegal_formatting = _illegal_formatting.search(fmt)
if illegal_formatting:
raise TypeError("strftime of dates before 1900 does not handle" + illegal_formatting.group(0))
year = dt.year
# For every non-leap year century, advance by
# 6 years to get into the 28-year repeat cycle
delta = 2000 - year
off = 6 * (delta // 100 + delta // 400)
year = year + off
# Move to around the year 2000
year = year + ((2000 - year) // 28) * 28
timetuple = dt.timetuple()
s1 = time.strftime(fmt, (year,) + timetuple[1:])
sites1 = _findall(s1, str(year))
s2 = time.strftime(fmt, (year+28,) + timetuple[1:])
sites2 = _findall(s2, str(year+28))
sites = []
for site in sites1:
if site in sites2:
sites.append(site)
s = s1
syear = "%4d" % (dt.year,)
for site in sites:
s = s[:site] + syear + s[site+4:]
return s

View File

@ -60,9 +60,17 @@ class LocalTimezone(tzinfo):
tt = (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.weekday(), 0, -1)
try:
stamp = time.mktime(tt)
except OverflowError:
# 32 bit systems can't handle dates after Jan 2038, so we fake it
# in that case (since we only care about the DST flag here).
except (OverflowError, ValueError):
# 32 bit systems can't handle dates after Jan 2038, and certain
# systems can't handle dates before ~1901-12-01:
#
# >>> time.mktime((1900, 1, 13, 0, 0, 0, 0, 0, 0))
# OverflowError: mktime argument out of range
# >>> time.mktime((1850, 1, 13, 0, 0, 0, 0, 0, 0))
# ValueError: year out of range
#
# In this case, we fake the date, because we only care about the
# DST flag.
tt = (2037,) + tt[1:]
stamp = time.mktime(tt)
tt = time.localtime(stamp)

View File

@ -0,0 +1,37 @@
r"""
>>> from datetime import date as original_date, datetime as original_datetime
>>> from django.utils.datetime_safe import date, datetime
>>> just_safe = (1900, 1, 1)
>>> just_unsafe = (1899, 12, 31, 23, 59, 59)
>>> really_old = (20, 1, 1)
>>> more_recent = (2006, 1, 1)
>>> original_datetime(*more_recent) == datetime(*more_recent)
True
>>> original_datetime(*really_old) == datetime(*really_old)
True
>>> original_date(*more_recent) == date(*more_recent)
True
>>> original_date(*really_old) == date(*really_old)
True
>>> original_date(*just_safe).strftime('%Y-%m-%d') == date(*just_safe).strftime('%Y-%m-%d')
True
>>> original_datetime(*just_safe).strftime('%Y-%m-%d') == datetime(*just_safe).strftime('%Y-%m-%d')
True
>>> date(*just_unsafe[:3]).strftime('%Y-%m-%d (weekday %w)')
'1899-12-31 (weekday 0)'
>>> date(*just_safe).strftime('%Y-%m-%d (weekday %w)')
'1900-01-01 (weekday 1)'
>>> datetime(*just_unsafe).strftime('%Y-%m-%d %H:%M:%S (weekday %w)')
'1899-12-31 23:59:59 (weekday 0)'
>>> datetime(*just_safe).strftime('%Y-%m-%d %H:%M:%S (weekday %w)')
'1900-01-01 00:00:00 (weekday 1)'
>>> date(*just_safe).strftime('%y') # %y will error before this date
'00'
>>> datetime(*just_safe).strftime('%y')
'00'
"""