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>
This commit is contained in:
Sjbrgsn 2019-12-21 11:45:54 +01:00 committed by Mariusz Felisiak
parent cf5d4701dc
commit b2bd08bb7a
6 changed files with 14 additions and 10 deletions

View File

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

View File

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

View File

@ -402,7 +402,7 @@ def slugify(value, allow_unicode=False):
value = unicodedata.normalize('NFKC', value) value = unicodedata.normalize('NFKC', value)
else: else:
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii') 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) return re.sub(r'[-\s]+', '-', value)

View File

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

View File

@ -4442,13 +4442,13 @@ class SeleniumTests(AdminSeleniumTestCase):
# Main form ---------------------------------------------------------- # Main form ----------------------------------------------------------
self.selenium.find_element_by_id('id_pubdate').send_keys('2012-02-18') self.selenium.find_element_by_id('id_pubdate').send_keys('2012-02-18')
self.select_option('#id_status', 'option two') 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') slug1 = self.selenium.find_element_by_id('id_slug1').get_attribute('value')
slug2 = self.selenium.find_element_by_id('id_slug2').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') 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(slug1, 'main-name-and-its-awesomeiiii-2012-02-18')
self.assertEqual(slug2, 'option-two-main-name-and-its-awesomeiii') 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\u0131') self.assertEqual(slug3, 'this-is-the-main-n\xe0m\xeb-and-its-aw\u03b5\u0161ome\u0131\u0131\u0131i')
# Stacked inlines ---------------------------------------------------- # Stacked inlines ----------------------------------------------------
# Initial inline # Initial inline
@ -4526,11 +4526,12 @@ class SeleniumTests(AdminSeleniumTestCase):
self.selenium.find_element_by_xpath('//input[@value="Save"]').click() self.selenium.find_element_by_xpath('//input[@value="Save"]').click()
self.assertEqual(MainPrepopulated.objects.all().count(), 1) self.assertEqual(MainPrepopulated.objects.all().count(), 1)
MainPrepopulated.objects.get( 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', pubdate='2012-02-18',
status='option two', status='option two',
slug1='main-name-and-its-awesomeiii-2012-02-18', slug1='main-name-and-its-awesomeiiii-2012-02-18',
slug2='option-two-main-name-and-its-awesomeiii', 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) self.assertEqual(RelatedPrepopulated.objects.all().count(), 4)
RelatedPrepopulated.objects.get( RelatedPrepopulated.objects.get(

View File

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