1
0
mirror of https://github.com/django/django.git synced 2024-12-22 09:05:43 +00:00

Fixed #11157 -- Stopped removing stop words in admin's prepopulated_fields.

Co-Authored-By: Andy Chosak <andy@chosak.org>
This commit is contained in:
Scott Cranfill 2020-05-20 13:11:30 -04:00 committed by Mariusz Felisiak
parent 922ff51f5a
commit 62f1655a64
6 changed files with 44 additions and 50 deletions

View File

@ -73,6 +73,7 @@ answer newbie questions, and generally made Django that much better:
Andrew Pinkham <http://AndrewsForge.com> Andrew Pinkham <http://AndrewsForge.com>
Andrews Medina <andrewsmedina@gmail.com> Andrews Medina <andrewsmedina@gmail.com>
Andriy Sokolovskiy <me@asokolovskiy.com> Andriy Sokolovskiy <me@asokolovskiy.com>
Andy Chosak <andy@chosak.org>
Andy Dustman <farcepest@gmail.com> Andy Dustman <farcepest@gmail.com>
Andy Gayton <andy-django@thecablelounge.com> Andy Gayton <andy-django@thecablelounge.com>
andy@jadedplanet.net andy@jadedplanet.net
@ -803,6 +804,7 @@ answer newbie questions, and generally made Django that much better:
schwank@gmail.com schwank@gmail.com
Scot Hacker <shacker@birdhouse.org> Scot Hacker <shacker@birdhouse.org>
Scott Barr <scott@divisionbyzero.com.au> Scott Barr <scott@divisionbyzero.com.au>
Scott Cranfill <scott@scottcranfill.com>
Scott Fitsimones <scott@airgara.ge> Scott Fitsimones <scott@airgara.ge>
Scott Pashley <github@scottpashley.co.uk> Scott Pashley <github@scottpashley.co.uk>
scott@staplefish.com scott@staplefish.com

View File

@ -148,23 +148,9 @@
function URLify(s, num_chars, allowUnicode) { function URLify(s, num_chars, allowUnicode) {
// changes, e.g., "Petty theft" to "petty-theft" // changes, e.g., "Petty theft" to "petty-theft"
// remove all these words from the string before urlifying
if (!allowUnicode) { if (!allowUnicode) {
s = downcode(s); s = downcode(s);
} }
const hasUnicodeChars = /[^\u0000-\u007f]/.test(s);
// Remove English words only if the string contains ASCII (English)
// characters.
if (!hasUnicodeChars) {
const removeList = [
"a", "an", "as", "at", "before", "but", "by", "for", "from",
"is", "in", "into", "like", "of", "off", "on", "onto", "per",
"since", "than", "the", "this", "that", "to", "up", "via",
"with"
];
const r = new RegExp('\\b(' + removeList.join('|') + ')\\b', 'gi');
s = s.replace(r, '');
}
s = s.toLowerCase(); // convert to lowercase 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) {

View File

@ -1096,8 +1096,7 @@ subclass::
automatically generate the value for ``SlugField`` fields from one or more automatically generate the value for ``SlugField`` fields from one or more
other fields. The generated value is produced by concatenating the values other fields. The generated value is produced by concatenating the values
of the source fields, and then by transforming that result into a valid of the source fields, and then by transforming that result into a valid
slug (e.g. substituting dashes for spaces; lowercasing ASCII letters; and slug (e.g. substituting dashes for spaces and lowercasing ASCII letters).
removing various English stop words such as 'a', 'an', 'as', and similar).
Prepopulated fields aren't modified by JavaScript after a value has been Prepopulated fields aren't modified by JavaScript after a value has been
saved. It's usually undesired that slugs change (which would cause an saved. It's usually undesired that slugs change (which would cause an
@ -1106,6 +1105,11 @@ subclass::
``prepopulated_fields`` doesn't accept ``DateTimeField``, ``ForeignKey``, ``prepopulated_fields`` doesn't accept ``DateTimeField``, ``ForeignKey``,
``OneToOneField``, and ``ManyToManyField`` fields. ``OneToOneField``, and ``ManyToManyField`` fields.
.. versionchanged:: 3.2
In older versions, various English stop words are removed from
generated values.
.. attribute:: ModelAdmin.preserve_filters .. attribute:: ModelAdmin.preserve_filters
The admin now preserves filters on the list view after creating, editing The admin now preserves filters on the list view after creating, editing

View File

@ -275,6 +275,9 @@ Miscellaneous
external build tool. The minified vendored JavaScript files packaged with the external build tool. The minified vendored JavaScript files packaged with the
admin (e.g. :ref:`jquery.min.js <contrib-admin-jquery>`) are still included. admin (e.g. :ref:`jquery.min.js <contrib-admin-jquery>`) are still included.
* :attr:`.ModelAdmin.prepopulated_fields` no longer strips English stop words,
such as ``'a'`` or ``'an'``.
.. _deprecated-features-3.2: .. _deprecated-features-3.2:
Features deprecated in 3.2 Features deprecated in 3.2

View File

@ -7,8 +7,8 @@ QUnit.test('empty string', function(assert) {
assert.strictEqual(URLify('', 8, true), ''); assert.strictEqual(URLify('', 8, true), '');
}); });
QUnit.test('strip nonessential words', function(assert) { QUnit.test('preserve nonessential words', function(assert) {
assert.strictEqual(URLify('the D is silent', 8, true), 'd-silent'); assert.strictEqual(URLify('the D is silent', 15, true), 'the-d-is-silent');
}); });
QUnit.test('strip non-URL characters', function(assert) { QUnit.test('strip non-URL characters', function(assert) {
@ -23,7 +23,6 @@ QUnit.test('trim trailing hyphens', function(assert) {
assert.strictEqual(URLify('D silent always', 9, true), 'd-silent'); assert.strictEqual(URLify('D silent always', 9, true), 'd-silent');
}); });
QUnit.test('do not remove English words if the string contains non-ASCII', function(assert) { QUnit.test('non-ASCII string', function(assert) {
// If removing English words wasn't skipped, the last 'a' would be removed.
assert.strictEqual(URLify('Kaupa-miða', 255, true), 'kaupa-miða'); assert.strictEqual(URLify('Kaupa-miða', 255, true), 'kaupa-miða');
}); });

View File

@ -4453,13 +4453,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(' 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-awesomeiiii-2012-02-18') self.assertEqual(slug1, 'the-main-name-and-its-awesomeiiii-2012-02-18')
self.assertEqual(slug2, 'option-two-main-name-and-its-awesomeiiii') self.assertEqual(slug2, 'option-two-the-main-name-and-its-awesomeiiii')
self.assertEqual(slug3, 'this-is-the-main-n\xe0m\xeb-and-its-aw\u03b5\u0161ome\u0131\u0131\u0131i') self.assertEqual(slug3, 'the-main-n\xe0m\xeb-and-its-aw\u03b5\u0161ome\u0131\u0131\u0131i')
# Stacked inlines ---------------------------------------------------- # Stacked inlines ----------------------------------------------------
# Initial inline # Initial inline
@ -4470,8 +4470,8 @@ class SeleniumTests(AdminSeleniumTestCase):
) )
slug1 = self.selenium.find_element_by_id('id_relatedprepopulated_set-0-slug1').get_attribute('value') slug1 = self.selenium.find_element_by_id('id_relatedprepopulated_set-0-slug1').get_attribute('value')
slug2 = self.selenium.find_element_by_id('id_relatedprepopulated_set-0-slug2').get_attribute('value') slug2 = self.selenium.find_element_by_id('id_relatedprepopulated_set-0-slug2').get_attribute('value')
self.assertEqual(slug1, 'here-stacked-inline-2011-12-17') self.assertEqual(slug1, 'here-is-a-stacked-inline-2011-12-17')
self.assertEqual(slug2, 'option-one-here-stacked-inline') self.assertEqual(slug2, 'option-one-here-is-a-stacked-inline')
initial_select2_inputs = self.selenium.find_elements_by_class_name('select2-selection') initial_select2_inputs = self.selenium.find_elements_by_class_name('select2-selection')
# Inline formsets have empty/invisible forms. # Inline formsets have empty/invisible forms.
# Only the 4 visible select2 inputs are initialized. # Only the 4 visible select2 inputs are initialized.
@ -4493,9 +4493,9 @@ class SeleniumTests(AdminSeleniumTestCase):
slug1 = self.selenium.find_element_by_id('id_relatedprepopulated_set-1-slug1').get_attribute('value') slug1 = self.selenium.find_element_by_id('id_relatedprepopulated_set-1-slug1').get_attribute('value')
slug2 = self.selenium.find_element_by_id('id_relatedprepopulated_set-1-slug2').get_attribute('value') slug2 = self.selenium.find_element_by_id('id_relatedprepopulated_set-1-slug2').get_attribute('value')
# 50 characters maximum for slug1 field # 50 characters maximum for slug1 field
self.assertEqual(slug1, 'now-you-have-another-stacked-inline-very-loooooooo') self.assertEqual(slug1, 'now-you-have-another-stacked-inline-with-a-very-lo')
# 60 characters maximum for slug2 field # 60 characters maximum for slug2 field
self.assertEqual(slug2, 'option-two-now-you-have-another-stacked-inline-very-looooooo') self.assertEqual(slug2, 'option-two-now-you-have-another-stacked-inline-with-a-very-l')
# Tabular inlines ---------------------------------------------------- # Tabular inlines ----------------------------------------------------
# Initial inline # Initial inline
@ -4506,8 +4506,8 @@ class SeleniumTests(AdminSeleniumTestCase):
) )
slug1 = self.selenium.find_element_by_id('id_relatedprepopulated_set-2-0-slug1').get_attribute('value') slug1 = self.selenium.find_element_by_id('id_relatedprepopulated_set-2-0-slug1').get_attribute('value')
slug2 = self.selenium.find_element_by_id('id_relatedprepopulated_set-2-0-slug2').get_attribute('value') slug2 = self.selenium.find_element_by_id('id_relatedprepopulated_set-2-0-slug2').get_attribute('value')
self.assertEqual(slug1, 'and-now-tabular-inline-1234-12-07') self.assertEqual(slug1, 'and-now-with-a-tabular-inline-1234-12-07')
self.assertEqual(slug2, 'option-two-and-now-tabular-inline') self.assertEqual(slug2, 'option-two-and-now-with-a-tabular-inline')
# Add an inline # Add an inline
# Button may be outside the browser frame. # Button may be outside the browser frame.
@ -4521,12 +4521,12 @@ class SeleniumTests(AdminSeleniumTestCase):
self.selenium.find_element_by_id('id_relatedprepopulated_set-2-1-pubdate').send_keys('1981-08-22') self.selenium.find_element_by_id('id_relatedprepopulated_set-2-1-pubdate').send_keys('1981-08-22')
self.select_option('#id_relatedprepopulated_set-2-1-status', 'option one') self.select_option('#id_relatedprepopulated_set-2-1-status', 'option one')
self.selenium.find_element_by_id('id_relatedprepopulated_set-2-1-name').send_keys( self.selenium.find_element_by_id('id_relatedprepopulated_set-2-1-name').send_keys(
r'a tÃbűlaŘ inline with ignored ;"&*^\%$#@-/`~ characters' r'tÃbűlaŘ inline with ignored ;"&*^\%$#@-/`~ characters'
) )
slug1 = self.selenium.find_element_by_id('id_relatedprepopulated_set-2-1-slug1').get_attribute('value') slug1 = self.selenium.find_element_by_id('id_relatedprepopulated_set-2-1-slug1').get_attribute('value')
slug2 = self.selenium.find_element_by_id('id_relatedprepopulated_set-2-1-slug2').get_attribute('value') slug2 = self.selenium.find_element_by_id('id_relatedprepopulated_set-2-1-slug2').get_attribute('value')
self.assertEqual(slug1, 'tabular-inline-ignored-characters-1981-08-22') self.assertEqual(slug1, 'tabular-inline-with-ignored-characters-1981-08-22')
self.assertEqual(slug2, 'option-one-tabular-inline-ignored-characters') self.assertEqual(slug2, 'option-one-tabular-inline-with-ignored-characters')
# Add an inline without an initial inline. # Add an inline without an initial inline.
# The button is outside of the browser frame. # The button is outside of the browser frame.
self.selenium.execute_script("window.scrollTo(0, document.body.scrollHeight);") self.selenium.execute_script("window.scrollTo(0, document.body.scrollHeight);")
@ -4540,42 +4540,42 @@ 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=' 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-awesomeiiii-2012-02-18', slug1='the-main-name-and-its-awesomeiiii-2012-02-18',
slug2='option-two-main-name-and-its-awesomeiiii', slug2='option-two-the-main-name-and-its-awesomeiiii',
slug3='this-is-the-main-nàmë-and-its-awεšomeıııi', slug3='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(
name=' here is a sŤāÇkeð inline ! ', name=' here is a sŤāÇkeð inline ! ',
pubdate='2011-12-17', pubdate='2011-12-17',
status='option one', status='option one',
slug1='here-stacked-inline-2011-12-17', slug1='here-is-a-stacked-inline-2011-12-17',
slug2='option-one-here-stacked-inline', slug2='option-one-here-is-a-stacked-inline',
) )
RelatedPrepopulated.objects.get( RelatedPrepopulated.objects.get(
# 75 characters in name field # 75 characters in name field
name=' now you haVe anöther sŤāÇkeð inline with a very ... loooooooooooooooooo', name=' now you haVe anöther sŤāÇkeð inline with a very ... loooooooooooooooooo',
pubdate='1999-01-25', pubdate='1999-01-25',
status='option two', status='option two',
slug1='now-you-have-another-stacked-inline-very-loooooooo', slug1='now-you-have-another-stacked-inline-with-a-very-lo',
slug2='option-two-now-you-have-another-stacked-inline-very-looooooo', slug2='option-two-now-you-have-another-stacked-inline-with-a-very-l',
) )
RelatedPrepopulated.objects.get( RelatedPrepopulated.objects.get(
name='And now, with a tÃbűlaŘ inline !!!', name='And now, with a tÃbűlaŘ inline !!!',
pubdate='1234-12-07', pubdate='1234-12-07',
status='option two', status='option two',
slug1='and-now-tabular-inline-1234-12-07', slug1='and-now-with-a-tabular-inline-1234-12-07',
slug2='option-two-and-now-tabular-inline', slug2='option-two-and-now-with-a-tabular-inline',
) )
RelatedPrepopulated.objects.get( RelatedPrepopulated.objects.get(
name=r'a tÃbűlaŘ inline with ignored ;"&*^\%$#@-/`~ characters', name=r'tÃbűlaŘ inline with ignored ;"&*^\%$#@-/`~ characters',
pubdate='1981-08-22', pubdate='1981-08-22',
status='option one', status='option one',
slug1='tabular-inline-ignored-characters-1981-08-22', slug1='tabular-inline-with-ignored-characters-1981-08-22',
slug2='option-one-tabular-inline-ignored-characters', slug2='option-one-tabular-inline-with-ignored-characters',
) )
def test_populate_existing_object(self): def test_populate_existing_object(self):
@ -4601,8 +4601,8 @@ class SeleniumTests(AdminSeleniumTestCase):
# The slugs got prepopulated since they were originally empty # The slugs got prepopulated since they were originally empty
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')
self.assertEqual(slug1, 'main-name-best-2012-02-18') self.assertEqual(slug1, 'this-is-the-main-name-the-best-2012-02-18')
self.assertEqual(slug2, 'option-two-main-name-best') self.assertEqual(slug2, 'option-two-this-is-the-main-name-the-best')
# Save the object # Save the object
with self.wait_page_loaded(): with self.wait_page_loaded():
@ -4614,8 +4614,8 @@ class SeleniumTests(AdminSeleniumTestCase):
# The slugs got prepopulated didn't change since they were originally not empty # The slugs got prepopulated didn't change since they were originally not empty
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')
self.assertEqual(slug1, 'main-name-best-2012-02-18') self.assertEqual(slug1, 'this-is-the-main-name-the-best-2012-02-18')
self.assertEqual(slug2, 'option-two-main-name-best') self.assertEqual(slug2, 'option-two-this-is-the-main-name-the-best')
def test_collapsible_fieldset(self): def test_collapsible_fieldset(self):
""" """