浏览代码

Fixed #30892 -- Fixed slugify() and admin's URLify.js for "İ".

Thanks Luis Nell for the implementation idea and very detailed report.

Co-Authored-By: Mariusz Felisiak <felisiak.mariusz@gmail.com>
Sjbrgsn 5 年之前
父节点
当前提交
b2bd08bb7a
共有 6 个文件被更改,包括 14 次插入10 次删除
  1. 1 0
      AUTHORS
  2. 2 1
      django/contrib/admin/static/admin/js/urlify.js
  3. 1 1
      django/utils/text.py
  4. 1 1
      docs/ref/utils.txt
  5. 8 7
      tests/admin_views/tests.py
  6. 1 0
      tests/utils_tests/test_text.py

+ 1 - 0
AUTHORS

@@ -185,6 +185,7 @@ answer newbie questions, and generally made Django that much better:
     Christian Metts
     Christian Oudard <christian.oudard@gmail.com>
     Christian Tanzer <tanzer@swing.co.at>
+    Christoffer Sjöbergsson
     Christophe Pettus <xof@thebuild.com>
     Christopher Adams <http://christopheradams.info>
     Christopher Babiak <chrisbabiak@gmail.com>

+ 2 - 1
django/contrib/admin/static/admin/js/urlify.js

@@ -177,6 +177,7 @@
             var r = new RegExp('\\b(' + removeList.join('|') + ')\\b', 'gi');
             s = s.replace(r, '');
         }
+        s = s.toLowerCase(); // convert to lowercase
         // if downcode doesn't hit, the char will be stripped here
         if (allowUnicode) {
             // Keep Unicode letters including both lowercase and uppercase
@@ -189,7 +190,7 @@
         s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens
         s = s.substring(0, num_chars); // trim to first num_chars chars
         s = s.replace(/-+$/g, ''); // trim any trailing hyphens
-        return s.toLowerCase(); // convert to lowercase
+        return s;
     }
     window.URLify = URLify;
 })();

+ 1 - 1
django/utils/text.py

@@ -402,7 +402,7 @@ def slugify(value, allow_unicode=False):
         value = unicodedata.normalize('NFKC', value)
     else:
         value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii')
-    value = re.sub(r'[^\w\s-]', '', value).strip().lower()
+    value = re.sub(r'[^\w\s-]', '', value.lower()).strip()
     return re.sub(r'[-\s]+', '-', value)
 
 

+ 1 - 1
docs/ref/utils.txt

@@ -830,10 +830,10 @@ appropriate entities.
     Converts a string to a URL slug by:
 
     #. Converting to ASCII if ``allow_unicode`` is ``False`` (the default).
+    #. Converting to lowercase.
     #. Removing characters that aren't alphanumerics, underscores, hyphens, or
        whitespace.
     #. Removing leading and trailing whitespace.
-    #. Converting to lowercase.
     #. Replacing any whitespace or repeated dashes with single dashes.
 
     For example::

+ 8 - 7
tests/admin_views/tests.py

@@ -4442,13 +4442,13 @@ class SeleniumTests(AdminSeleniumTestCase):
         # Main form ----------------------------------------------------------
         self.selenium.find_element_by_id('id_pubdate').send_keys('2012-02-18')
         self.select_option('#id_status', 'option two')
-        self.selenium.find_element_by_id('id_name').send_keys(' this is the mAin nÀMë and it\'s awεšomeııı')
+        self.selenium.find_element_by_id('id_name').send_keys(' this is the mAin nÀMë and it\'s awεšomeıııİ')
         slug1 = self.selenium.find_element_by_id('id_slug1').get_attribute('value')
         slug2 = self.selenium.find_element_by_id('id_slug2').get_attribute('value')
         slug3 = self.selenium.find_element_by_id('id_slug3').get_attribute('value')
-        self.assertEqual(slug1, 'main-name-and-its-awesomeiii-2012-02-18')
-        self.assertEqual(slug2, 'option-two-main-name-and-its-awesomeiii')
-        self.assertEqual(slug3, 'this-is-the-main-n\xe0m\xeb-and-its-aw\u03b5\u0161ome\u0131\u0131\u0131')
+        self.assertEqual(slug1, 'main-name-and-its-awesomeiiii-2012-02-18')
+        self.assertEqual(slug2, 'option-two-main-name-and-its-awesomeiiii')
+        self.assertEqual(slug3, 'this-is-the-main-n\xe0m\xeb-and-its-aw\u03b5\u0161ome\u0131\u0131\u0131i')
 
         # Stacked inlines ----------------------------------------------------
         # Initial inline
@@ -4526,11 +4526,12 @@ class SeleniumTests(AdminSeleniumTestCase):
             self.selenium.find_element_by_xpath('//input[@value="Save"]').click()
         self.assertEqual(MainPrepopulated.objects.all().count(), 1)
         MainPrepopulated.objects.get(
-            name=' this is the mAin nÀMë and it\'s awεšomeııı',
+            name=' this is the mAin nÀMë and it\'s awεšomeıııİ',
             pubdate='2012-02-18',
             status='option two',
-            slug1='main-name-and-its-awesomeiii-2012-02-18',
-            slug2='option-two-main-name-and-its-awesomeiii',
+            slug1='main-name-and-its-awesomeiiii-2012-02-18',
+            slug2='option-two-main-name-and-its-awesomeiiii',
+            slug3='this-is-the-main-nàmë-and-its-awεšomeıııi',
         )
         self.assertEqual(RelatedPrepopulated.objects.all().count(), 4)
         RelatedPrepopulated.objects.get(

+ 1 - 0
tests/utils_tests/test_text.py

@@ -196,6 +196,7 @@ class TestUtilsText(SimpleTestCase):
             ('foo ıç bar', 'foo-ıç-bar', True),
             ('    foo ıç bar', 'foo-ıç-bar', True),
             ('你好', '你好', True),
+            ('İstanbul', 'istanbul', True),
         )
         for value, output, is_unicode in items:
             self.assertEqual(text.slugify(value, allow_unicode=is_unicode), output)