Fixed #22502 -- Fixed microseconds/default/form interaction
Made explicit lack of microsecond handling by built-in datetime form fields. Used that explicitness to appropriately nix microsecond values in bound fields. Thanks Claude Paroz for the review.
This commit is contained in:
parent
35e1b1efab
commit
a5de0df58b
1
AUTHORS
1
AUTHORS
|
@ -137,6 +137,7 @@ answer newbie questions, and generally made Django that much better:
|
|||
btoll@bestweb.net
|
||||
Jonathan Buchanan <jonathan.buchanan@gmail.com>
|
||||
Jacob Burch <jacobburch@gmail.com>
|
||||
Stephen Burrows <stephen.r.burrows@gmail.com>
|
||||
Max Burstein <http://maxburstein.com>
|
||||
Keith Bussell <kbussell@gmail.com>
|
||||
C8E
|
||||
|
|
|
@ -6,6 +6,7 @@ from __future__ import unicode_literals
|
|||
|
||||
from collections import OrderedDict
|
||||
import copy
|
||||
import datetime
|
||||
import warnings
|
||||
|
||||
from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
|
||||
|
@ -593,6 +594,11 @@ class BoundField(object):
|
|||
data = self.form.initial.get(self.name, self.field.initial)
|
||||
if callable(data):
|
||||
data = data()
|
||||
# If this is an auto-generated default date, nix the
|
||||
# microseconds for standardized handling. See #22502.
|
||||
if (isinstance(data, (datetime.datetime, datetime.time)) and
|
||||
not getattr(self.field.widget, 'supports_microseconds', True)):
|
||||
data = data.replace(microsecond=0)
|
||||
else:
|
||||
data = self.field.bound_data(
|
||||
self.data, self.form.initial.get(self.name, self.field.initial)
|
||||
|
|
|
@ -419,6 +419,7 @@ class Textarea(Widget):
|
|||
|
||||
class DateTimeBaseInput(TextInput):
|
||||
format_key = ''
|
||||
supports_microseconds = False
|
||||
|
||||
def __init__(self, attrs=None, format=None):
|
||||
super(DateTimeBaseInput, self).__init__(attrs)
|
||||
|
@ -846,6 +847,7 @@ class SplitDateTimeWidget(MultiWidget):
|
|||
"""
|
||||
A Widget that splits datetime input into two <input type="text"> boxes.
|
||||
"""
|
||||
supports_microseconds = False
|
||||
|
||||
def __init__(self, attrs=None, date_format=None, time_format=None):
|
||||
widgets = (DateInput(attrs=attrs, format=date_format),
|
||||
|
|
|
@ -11,10 +11,10 @@ from django.core.files.uploadedfile import SimpleUploadedFile
|
|||
from django.core.validators import RegexValidator
|
||||
from django.forms import (
|
||||
BooleanField, CharField, CheckboxSelectMultiple, ChoiceField, DateField,
|
||||
EmailField, FileField, FloatField, Form, forms, HiddenInput, IntegerField,
|
||||
MultipleChoiceField, MultipleHiddenInput, MultiValueField,
|
||||
DateTimeField, EmailField, FileField, FloatField, Form, forms, HiddenInput,
|
||||
IntegerField, MultipleChoiceField, MultipleHiddenInput, MultiValueField,
|
||||
NullBooleanField, PasswordInput, RadioSelect, Select, SplitDateTimeField,
|
||||
Textarea, TextInput, ValidationError, widgets,
|
||||
Textarea, TextInput, TimeField, ValidationError, widgets
|
||||
)
|
||||
from django.forms.utils import ErrorList
|
||||
from django.http import QueryDict
|
||||
|
@ -1321,6 +1321,29 @@ class FormsTestCase(TestCase):
|
|||
self.assertEqual(bound['password'].value(), 'foo')
|
||||
self.assertEqual(unbound['password'].value(), None)
|
||||
|
||||
def test_initial_datetime_values(self):
|
||||
now = datetime.datetime.now()
|
||||
# Nix microseconds (since they should be ignored). #22502
|
||||
now_no_ms = now.replace(microsecond=0)
|
||||
if now == now_no_ms:
|
||||
now = now.replace(microsecond=1)
|
||||
|
||||
def delayed_now():
|
||||
return now
|
||||
|
||||
def delayed_now_time():
|
||||
return now.time()
|
||||
|
||||
class DateTimeForm(Form):
|
||||
auto_timestamp = DateTimeField(initial=delayed_now)
|
||||
auto_time_only = TimeField(initial=delayed_now_time)
|
||||
supports_microseconds = DateTimeField(initial=delayed_now, widget=TextInput)
|
||||
|
||||
unbound = DateTimeForm()
|
||||
self.assertEqual(unbound['auto_timestamp'].value(), now_no_ms)
|
||||
self.assertEqual(unbound['auto_time_only'].value(), now_no_ms.time())
|
||||
self.assertEqual(unbound['supports_microseconds'].value(), now)
|
||||
|
||||
def test_help_text(self):
|
||||
# You can specify descriptive text for a field by using the 'help_text' argument)
|
||||
class UserRegistration(Form):
|
||||
|
|
Loading…
Reference in New Issue