summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSjbrgsn <chsnot@gmail.com>2019-12-21 11:45:54 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-12-30 20:47:22 +0100
commitb2bd08bb7a912a1504f5fb5018f5317e6b5423cd (patch)
treec481e9b848b285755f872554ed0b828e5256aee9
parentcf5d4701dc12ad69d51042b0d7e81e4a54de4bd7 (diff)
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>
-rw-r--r--AUTHORS1
-rw-r--r--django/contrib/admin/static/admin/js/urlify.js3
-rw-r--r--django/utils/text.py2
-rw-r--r--docs/ref/utils.txt2
-rw-r--r--tests/admin_views/tests.py15
-rw-r--r--tests/utils_tests/test_text.py1
6 files changed, 14 insertions, 10 deletions
diff --git a/AUTHORS b/AUTHORS
index 8b4492cc5c..5b7d67d06c 100644
--- a/AUTHORS
+++ b/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>
diff --git a/django/contrib/admin/static/admin/js/urlify.js b/django/contrib/admin/static/admin/js/urlify.js
index c3342b9d59..8a3842c9bc 100644
--- a/django/contrib/admin/static/admin/js/urlify.js
+++ b/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;
})();
diff --git a/django/utils/text.py b/django/utils/text.py
index 5e1409116e..110e088ddf 100644
--- a/django/utils/text.py
+++ b/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)
diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt
index d8af302c0e..4dafc9cee5 100644
--- a/docs/ref/utils.txt
+++ b/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::
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index 71db79ae2e..4b4b118987 100644
--- a/tests/admin_views/tests.py
+++ b/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(
diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py
index b904c228b9..66dbd5b366 100644
--- a/tests/utils_tests/test_text.py
+++ b/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)