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:
parent
922ff51f5a
commit
62f1655a64
2
AUTHORS
2
AUTHORS
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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');
|
||||||
});
|
});
|
||||||
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user