Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Fixed #18767: Admin's calendar for datetime fields doesn't show right values with russian and some other locales #294

Closed
wants to merge 2 commits into from

3 participants

Alexey Boriskin Tim Graham Aymeric Augustin
Alexey Boriskin
uruz commented August 19, 2012

Solution includes incomplete implementation of strptime. I've included test into commit.

and others added some commits August 19, 2012
Alexey Boriskin uruz referenced this pull request from a commit in uruz/django January 16, 2013
Alexey Boriskin Integrate pull request #294 into #618 3a719a6
Fabian Büchler fabianbuechler referenced this pull request from a commit in fabianbuechler/django January 17, 2013
Fabian Büchler Integrate pull request #294 into #618. 6fc8933
Alexey Boriskin uruz referenced this pull request from a commit February 19, 2013
Commit has since been removed from the repository and is no longer available.
Alexey Boriskin uruz referenced this pull request from a commit in uruz/django January 17, 2013
Fabian Büchler Integrate pull request #294 into #618. 36b9d40
Tim Graham
Owner

No longer merges cleanly. Also looks like it was incorporated in #618.

Tim Graham timgraham closed this March 01, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 2 unique commits by 2 authors.

Aug 19, 2012
Aymeric Augustin Merge pull request #293 from mjtamlyn/patch-1
Fixed indentation in the Python3 docs
a2ba026
Alexey Boriskin Fixed #18767: Admin's calendar for datetime fields doesn't show right…
… values with russian and some other locales
48835e9
This page is out of date. Refresh to see the latest.
54  django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js
@@ -214,15 +214,57 @@ var DateTimeShortcuts = {
214 214
         var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1+num)
215 215
         var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName+num)
216 216
         var inp = DateTimeShortcuts.calendarInputs[num];
  217
+        var value = inp.value;
217 218
 
218 219
         // Determine if the current value in the input has a valid date.
219 220
         // If so, draw the calendar with that date's year and month.
220  
-        if (inp.value) {
221  
-            var date_parts = inp.value.split('-');
222  
-            var year = date_parts[0];
223  
-            var month = parseFloat(date_parts[1]);
224  
-            if (year.match(/\d\d\d\d/) && month >= 1 && month <= 12) {
225  
-                DateTimeShortcuts.calendars[num].drawDate(month, year);
  221
+        if (value) {
  222
+            //Poor and incomplete port of python's _strptime module.
  223
+            //We only look for %Y, %y, %m, %d formats.
  224
+            //That should be enough for every locale included with django,
  225
+            //but still may not work with custom format files.
  226
+            var format = get_format('DATE_INPUT_FORMATS')[0];
  227
+            var regexes = {
  228
+                'Y' : '(\\d{4})',
  229
+                'y' : '(\\d{2})',
  230
+                'm' : '(\\d{2})',
  231
+                'd' : '(\\d{2})',
  232
+                '%' : '%'
  233
+            };
  234
+            var directives = '';
  235
+            var processed_format = '';
  236
+            var directive_index;
  237
+            //Escape those symbols in format that are special for regular expressions syntax
  238
+            format = format.replace(new RegExp("([\\.^$*+?\(\){}\[\]|])", 'g'), '\\$&');
  239
+            while (format.indexOf('%') !== -1){
  240
+                directive_index = format.indexOf('%') + 1;
  241
+                processed_format = processed_format + format.substr(0, directive_index-1) + regexes[format[directive_index]];
  242
+                directives += format[directive_index];
  243
+                format = format.substr(directive_index+1);
  244
+            }
  245
+            var format_regexp = new RegExp('^'+processed_format+'$');
  246
+            if ( (directives.toLowerCase().indexOf('y') !== -1) && (directives.indexOf('m') !== -1)){
  247
+                var groups = format_regexp.exec(value);
  248
+                var year;
  249
+                var year_index = directives.indexOf('Y');
  250
+                if (year_index !== -1){
  251
+                    year = parseInt(groups[year_index+1]);
  252
+                }else{
  253
+                    year_index = directives.indexOf('y');
  254
+                    year = parseInt(groups[year_index+1]);
  255
+                    if (year <= 68){
  256
+                        year += 2000;
  257
+                    }else{
  258
+                        year += 1900;
  259
+                    }
  260
+                }
  261
+                var month = parseInt(groups[directives.indexOf('m')+1]);
  262
+                if ((month < 1) || (month > 12)){
  263
+                    month = undefined;
  264
+                }
  265
+                if (year && month){
  266
+                    DateTimeShortcuts.calendars[num].drawDate(month, year);
  267
+                }
226 268
             }
227 269
         }
228 270
 
38  tests/regressiontests/admin_widgets/tests.py
@@ -14,11 +14,15 @@
14 14
 from django.test import TestCase as DjangoTestCase
15 15
 from django.test.utils import override_settings
16 16
 from django.utils import translation
  17
+from django.utils.importlib import import_module
17 18
 from django.utils.html import conditional_escape
18 19
 from django.utils.unittest import TestCase
  20
+import os
  21
+
19 22
 
20 23
 from . import models
21 24
 from .widgetadmin import site as widget_admin_site
  25
+import gettext as gettext_module
22 26
 
23 27
 
24 28
 admin_static_prefix = lambda: {
@@ -464,6 +468,40 @@ def test_show_hide_date_time_picker_widgets(self):
464 468
         self.assertEqual(
465 469
             self.get_css_value('#clockbox0', 'display'), 'none')
466 470
 
  471
+    def test_show_correct_date(self):
  472
+        '''
  473
+        Ensure that click on date widget shows correct date for every
  474
+        locale included with django
  475
+        '''
  476
+        self.admin_login(username='super', password='secret', login_url='/')
  477
+        birthdate = datetime(1969, 7, 15)
  478
+        member = models.Member(name = 'Alexander Vasilyev', birthdate = birthdate, gender = 'M')
  479
+        member.save()
  480
+        month_string = 'January February March April May June July August September October November December'
  481
+        path = os.path.join(os.path.dirname(import_module('django.contrib.admin').__file__), 'locale')
  482
+        for language_code, language_name in settings.LANGUAGES:
  483
+            try:
  484
+                catalog = gettext_module.translation('djangojs', path, [language_code])
  485
+            except IOError:
  486
+                continue
  487
+            if month_string in catalog._catalog:
  488
+                month_names = catalog._catalog[month_string]
  489
+            else:
  490
+                month_names = month_string
  491
+            july_translation = month_names.split(' ')[6]
  492
+            expected_caption = '{0:s} {1:d}'.format(july_translation, 1969)
  493
+            with override_settings(LANGUAGE_CODE = language_code):
  494
+                self.selenium.get('{}{}'.format(self.live_server_url, '/admin_widgets/member/{}/'.format(member.pk)))
  495
+                self.assertEqual(self.get_css_value('#calendarbox0', 'display'), 'none')
  496
+                # Click the calendar icon
  497
+                self.selenium.find_element_by_id('calendarlink0').click()
  498
+                # Check that the date picker is visible
  499
+                self.assertEqual(self.get_css_value('#calendarbox0', 'display'), 'block')
  500
+                # Check that calendar's caption is what we expected
  501
+                caption = self.selenium.find_element_by_css_selector('#calendarin0>table>caption').text
  502
+                self.assertEqual(caption, expected_caption)
  503
+
  504
+
467 505
 class DateTimePickerSeleniumChromeTests(DateTimePickerSeleniumFirefoxTests):
468 506
     webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver'
469 507
 
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.