Commit b057a8b2 authored by Jannis Leidel's avatar Jannis Leidel
Browse files

Fixed #13560 -- Fixed localization of widgets.

Particularly this fixes the SplitDateTimeField and the AdminDateWidget by localizating the widget's value in its render method instead of the form field. Thanks to David Danier for the report and Russell for help with the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@13296 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 8a6cb3d9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ class FilteredSelectMultiple(forms.SelectMultiple):
            (name, self.verbose_name.replace('"', '\\"'), int(self.is_stacked), settings.ADMIN_MEDIA_PREFIX))
        return mark_safe(u''.join(output))

class AdminDateWidget(forms.DateTimeInput):
class AdminDateWidget(forms.DateInput):
    class Media:
        js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js",
              settings.ADMIN_MEDIA_PREFIX + "js/admin/DateTimeShortcuts.js")
+9 −5
Original line number Diff line number Diff line
@@ -105,6 +105,8 @@ class Field(object):

        # Trigger the localization machinery if needed.
        self.localize = localize
        if self.localize:
            widget.is_localized = True

        # Hook into self.widget_attrs() for any Field-specific HTML attributes.
        extra_attrs = self.widget_attrs(widget)
@@ -125,9 +127,6 @@ class Field(object):

        self.validators = self.default_validators + validators

    def localize_value(self, value):
        return formats.localize_input(value)

    def to_python(self, value):
        return value

@@ -843,9 +842,14 @@ class SplitDateTimeField(MultiValueField):
        errors = self.default_error_messages.copy()
        if 'error_messages' in kwargs:
            errors.update(kwargs['error_messages'])
        localize = kwargs.get('localize', False)
        fields = (
            DateField(input_formats=input_date_formats, error_messages={'invalid': errors['invalid_date']}),
            TimeField(input_formats=input_time_formats, error_messages={'invalid': errors['invalid_time']}),
            DateField(input_formats=input_date_formats,
                      error_messages={'invalid': errors['invalid_date']},
                      localize=localize),
            TimeField(input_formats=input_time_formats,
                      error_messages={'invalid': errors['invalid_time']},
                      localize=localize),
        )
        super(SplitDateTimeField, self).__init__(fields, *args, **kwargs)

+0 −2
Original line number Diff line number Diff line
@@ -443,8 +443,6 @@ class BoundField(StrAndUnicode):
            name = self.html_name
        else:
            name = self.html_initial_name
        if self.field.localize:
            data = self.field.localize_value(data)
        return widget.render(name, data, attrs=attrs)

    def as_text(self, attrs=None, **kwargs):
+27 −27
Original line number Diff line number Diff line
@@ -10,7 +10,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 formats
from django.utils import datetime_safe, formats
import time
import datetime
from util import flatatt
@@ -133,6 +133,7 @@ class Widget(object):
    __metaclass__ = MediaDefiningClass
    is_hidden = False          # Determines whether this corresponds to an <input type="hidden">.
    needs_multipart_form = False # Determines does this widget need multipart-encrypted form
    is_localized = False

    def __init__(self, attrs=None):
        if attrs is not None:
@@ -208,12 +209,18 @@ class Input(Widget):
    """
    input_type = None # Subclasses must define this.

    def _format_value(self, value):
        if self.is_localized:
            return formats.localize_input(value)
        return value

    def render(self, name, value, attrs=None):
        if value is None: value = ''
        if value is None:
            value = ''
        final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
        if value != '':
            # Only add the 'value' attribute if a value is non-empty.
            final_attrs['value'] = force_unicode(value)
            final_attrs['value'] = force_unicode(self._format_value(value))
        return mark_safe(u'<input%s />' % flatatt(final_attrs))

class TextInput(Input):
@@ -295,7 +302,7 @@ class Textarea(Widget):

class DateInput(Input):
    input_type = 'text'
    format = None
    format = '%Y-%m-%d'     # '2006-10-25'

    def __init__(self, attrs=None, format=None):
        super(DateInput, self).__init__(attrs)
@@ -303,16 +310,13 @@ class DateInput(Input):
            self.format = format

    def _format_value(self, value):
        if value is None:
            return ''
        if self.is_localized:
            return formats.localize_input(value)
        elif hasattr(value, 'strftime'):
            return formats.localize_input(value, self.format)
            value = datetime_safe.new_date(value)
            return value.strftime(self.format)
        return value

    def render(self, name, value, attrs=None):
        value = self._format_value(value)
        return super(DateInput, self).render(name, value, attrs)

    def _has_changed(self, initial, data):
        # If our field has show_hidden_initial=True, initial will be a string
        # formatted by HiddenInput using formats.localize_input, which is not
@@ -326,7 +330,7 @@ class DateInput(Input):

class DateTimeInput(Input):
    input_type = 'text'
    format = None
    format = '%Y-%m-%d %H:%M:%S'     # '2006-10-25 14:30:59'

    def __init__(self, attrs=None, format=None):
        super(DateTimeInput, self).__init__(attrs)
@@ -334,16 +338,13 @@ class DateTimeInput(Input):
            self.format = format

    def _format_value(self, value):
        if value is None:
            return ''
        if self.is_localized:
            return formats.localize_input(value)
        elif hasattr(value, 'strftime'):
            return formats.localize_input(value, self.format)
            value = datetime_safe.new_datetime(value)
            return value.strftime(self.format)
        return value

    def render(self, name, value, attrs=None):
        value = self._format_value(value)
        return super(DateTimeInput, self).render(name, value, attrs)

    def _has_changed(self, initial, data):
        # If our field has show_hidden_initial=True, initial will be a string
        # formatted by HiddenInput using formats.localize_input, which is not
@@ -357,7 +358,7 @@ class DateTimeInput(Input):

class TimeInput(Input):
    input_type = 'text'
    format = None
    format = '%H:%M:%S'     # '14:30:59'

    def __init__(self, attrs=None, format=None):
        super(TimeInput, self).__init__(attrs)
@@ -365,16 +366,12 @@ class TimeInput(Input):
            self.format = format

    def _format_value(self, value):
        if value is None:
            return ''
        if self.is_localized:
            return formats.localize_input(value)
        elif hasattr(value, 'strftime'):
            return formats.localize_input(value, self.format)
            return value.strftime(self.format)
        return value

    def render(self, name, value, attrs=None):
        value = self._format_value(value)
        return super(TimeInput, self).render(name, value, attrs)

    def _has_changed(self, initial, data):
        # If our field has show_hidden_initial=True, initial will be a string
        # formatted by HiddenInput using formats.localize_input, which is not
@@ -674,6 +671,9 @@ class MultiWidget(Widget):
        super(MultiWidget, self).__init__(attrs)

    def render(self, name, value, attrs=None):
        if self.is_localized:
            for widget in self.widgets:
                widget.is_localized = self.is_localized
        # value is a list of values, each corresponding to a widget
        # in self.widgets.
        if not isinstance(value, list):
+1 −0
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ HTML escaped.
<p class="datetime">Date: <input value="2007-12-01" type="text" class="vDateField" name="test_0" size="10" /><br />Time: <input value="09:30:00" type="text" class="vTimeField" name="test_1" size="8" /></p>
>>> activate('de-at')
>>> settings.USE_L10N = True
>>> w.is_localized = True
>>> print conditional_escape(w.render('test', datetime(2007, 12, 1, 9, 30)))
<p class="datetime">Datum: <input value="01.12.2007" type="text" class="vDateField" name="test_0" size="10" /><br />Zeit: <input value="09:30:00" type="text" class="vTimeField" name="test_1" size="8" /></p>
>>> deactivate()
Loading