Skip to content

Commit 62f1655

Browse files
Scott Cranfillchosak
authored andcommitted
Fixed django#11157 -- Stopped removing stop words in admin's prepopulated_fields.
Co-Authored-By: Andy Chosak <andy@chosak.org>
1 parent 922ff51 commit 62f1655

File tree

6 files changed

+44
-50
lines changed

6 files changed

+44
-50
lines changed

AUTHORS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ answer newbie questions, and generally made Django that much better:
7373
Andrew Pinkham <http://AndrewsForge.com>
7474
Andrews Medina <andrewsmedina@gmail.com>
7575
Andriy Sokolovskiy <me@asokolovskiy.com>
76+
Andy Chosak <andy@chosak.org>
7677
Andy Dustman <farcepest@gmail.com>
7778
Andy Gayton <andy-django@thecablelounge.com>
7879
andy@jadedplanet.net
@@ -803,6 +804,7 @@ answer newbie questions, and generally made Django that much better:
803804
schwank@gmail.com
804805
Scot Hacker <shacker@birdhouse.org>
805806
Scott Barr <scott@divisionbyzero.com.au>
807+
Scott Cranfill <scott@scottcranfill.com>
806808
Scott Fitsimones <scott@airgara.ge>
807809
Scott Pashley <github@scottpashley.co.uk>
808810
scott@staplefish.com

django/contrib/admin/static/admin/js/urlify.js

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -148,23 +148,9 @@
148148

149149
function URLify(s, num_chars, allowUnicode) {
150150
// changes, e.g., "Petty theft" to "petty-theft"
151-
// remove all these words from the string before urlifying
152151
if (!allowUnicode) {
153152
s = downcode(s);
154153
}
155-
const hasUnicodeChars = /[^\u0000-\u007f]/.test(s);
156-
// Remove English words only if the string contains ASCII (English)
157-
// characters.
158-
if (!hasUnicodeChars) {
159-
const removeList = [
160-
"a", "an", "as", "at", "before", "but", "by", "for", "from",
161-
"is", "in", "into", "like", "of", "off", "on", "onto", "per",
162-
"since", "than", "the", "this", "that", "to", "up", "via",
163-
"with"
164-
];
165-
const r = new RegExp('\\b(' + removeList.join('|') + ')\\b', 'gi');
166-
s = s.replace(r, '');
167-
}
168154
s = s.toLowerCase(); // convert to lowercase
169155
// if downcode doesn't hit, the char will be stripped here
170156
if (allowUnicode) {

docs/ref/contrib/admin/index.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,8 +1096,7 @@ subclass::
10961096
automatically generate the value for ``SlugField`` fields from one or more
10971097
other fields. The generated value is produced by concatenating the values
10981098
of the source fields, and then by transforming that result into a valid
1099-
slug (e.g. substituting dashes for spaces; lowercasing ASCII letters; and
1100-
removing various English stop words such as 'a', 'an', 'as', and similar).
1099+
slug (e.g. substituting dashes for spaces and lowercasing ASCII letters).
11011100

11021101
Prepopulated fields aren't modified by JavaScript after a value has been
11031102
saved. It's usually undesired that slugs change (which would cause an
@@ -1106,6 +1105,11 @@ subclass::
11061105
``prepopulated_fields`` doesn't accept ``DateTimeField``, ``ForeignKey``,
11071106
``OneToOneField``, and ``ManyToManyField`` fields.
11081107

1108+
.. versionchanged:: 3.2
1109+
1110+
In older versions, various English stop words are removed from
1111+
generated values.
1112+
11091113
.. attribute:: ModelAdmin.preserve_filters
11101114

11111115
The admin now preserves filters on the list view after creating, editing

docs/releases/3.2.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,9 @@ Miscellaneous
275275
external build tool. The minified vendored JavaScript files packaged with the
276276
admin (e.g. :ref:`jquery.min.js <contrib-admin-jquery>`) are still included.
277277

278+
* :attr:`.ModelAdmin.prepopulated_fields` no longer strips English stop words,
279+
such as ``'a'`` or ``'an'``.
280+
278281
.. _deprecated-features-3.2:
279282

280283
Features deprecated in 3.2

js_tests/admin/URLify.test.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ QUnit.test('empty string', function(assert) {
77
assert.strictEqual(URLify('', 8, true), '');
88
});
99

10-
QUnit.test('strip nonessential words', function(assert) {
11-
assert.strictEqual(URLify('the D is silent', 8, true), 'd-silent');
10+
QUnit.test('preserve nonessential words', function(assert) {
11+
assert.strictEqual(URLify('the D is silent', 15, true), 'the-d-is-silent');
1212
});
1313

1414
QUnit.test('strip non-URL characters', function(assert) {
@@ -23,7 +23,6 @@ QUnit.test('trim trailing hyphens', function(assert) {
2323
assert.strictEqual(URLify('D silent always', 9, true), 'd-silent');
2424
});
2525

26-
QUnit.test('do not remove English words if the string contains non-ASCII', function(assert) {
27-
// If removing English words wasn't skipped, the last 'a' would be removed.
26+
QUnit.test('non-ASCII string', function(assert) {
2827
assert.strictEqual(URLify('Kaupa-miða', 255, true), 'kaupa-miða');
2928
});

tests/admin_views/tests.py

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4453,13 +4453,13 @@ def test_prepopulated_fields(self):
44534453
# Main form ----------------------------------------------------------
44544454
self.selenium.find_element_by_id('id_pubdate').send_keys('2012-02-18')
44554455
self.select_option('#id_status', 'option two')
4456-
self.selenium.find_element_by_id('id_name').send_keys(' this is the mAin nÀMë and it\'s awεšomeıııİ')
4456+
self.selenium.find_element_by_id('id_name').send_keys(' the mAin nÀMë and it\'s awεšomeıııİ')
44574457
slug1 = self.selenium.find_element_by_id('id_slug1').get_attribute('value')
44584458
slug2 = self.selenium.find_element_by_id('id_slug2').get_attribute('value')
44594459
slug3 = self.selenium.find_element_by_id('id_slug3').get_attribute('value')
4460-
self.assertEqual(slug1, 'main-name-and-its-awesomeiiii-2012-02-18')
4461-
self.assertEqual(slug2, 'option-two-main-name-and-its-awesomeiiii')
4462-
self.assertEqual(slug3, 'this-is-the-main-n\xe0m\xeb-and-its-aw\u03b5\u0161ome\u0131\u0131\u0131i')
4460+
self.assertEqual(slug1, 'the-main-name-and-its-awesomeiiii-2012-02-18')
4461+
self.assertEqual(slug2, 'option-two-the-main-name-and-its-awesomeiiii')
4462+
self.assertEqual(slug3, 'the-main-n\xe0m\xeb-and-its-aw\u03b5\u0161ome\u0131\u0131\u0131i')
44634463

44644464
# Stacked inlines ----------------------------------------------------
44654465
# Initial inline
@@ -4470,8 +4470,8 @@ def test_prepopulated_fields(self):
44704470
)
44714471
slug1 = self.selenium.find_element_by_id('id_relatedprepopulated_set-0-slug1').get_attribute('value')
44724472
slug2 = self.selenium.find_element_by_id('id_relatedprepopulated_set-0-slug2').get_attribute('value')
4473-
self.assertEqual(slug1, 'here-stacked-inline-2011-12-17')
4474-
self.assertEqual(slug2, 'option-one-here-stacked-inline')
4473+
self.assertEqual(slug1, 'here-is-a-stacked-inline-2011-12-17')
4474+
self.assertEqual(slug2, 'option-one-here-is-a-stacked-inline')
44754475
initial_select2_inputs = self.selenium.find_elements_by_class_name('select2-selection')
44764476
# Inline formsets have empty/invisible forms.
44774477
# Only the 4 visible select2 inputs are initialized.
@@ -4493,9 +4493,9 @@ def test_prepopulated_fields(self):
44934493
slug1 = self.selenium.find_element_by_id('id_relatedprepopulated_set-1-slug1').get_attribute('value')
44944494
slug2 = self.selenium.find_element_by_id('id_relatedprepopulated_set-1-slug2').get_attribute('value')
44954495
# 50 characters maximum for slug1 field
4496-
self.assertEqual(slug1, 'now-you-have-another-stacked-inline-very-loooooooo')
4496+
self.assertEqual(slug1, 'now-you-have-another-stacked-inline-with-a-very-lo')
44974497
# 60 characters maximum for slug2 field
4498-
self.assertEqual(slug2, 'option-two-now-you-have-another-stacked-inline-very-looooooo')
4498+
self.assertEqual(slug2, 'option-two-now-you-have-another-stacked-inline-with-a-very-l')
44994499

45004500
# Tabular inlines ----------------------------------------------------
45014501
# Initial inline
@@ -4506,8 +4506,8 @@ def test_prepopulated_fields(self):
45064506
)
45074507
slug1 = self.selenium.find_element_by_id('id_relatedprepopulated_set-2-0-slug1').get_attribute('value')
45084508
slug2 = self.selenium.find_element_by_id('id_relatedprepopulated_set-2-0-slug2').get_attribute('value')
4509-
self.assertEqual(slug1, 'and-now-tabular-inline-1234-12-07')
4510-
self.assertEqual(slug2, 'option-two-and-now-tabular-inline')
4509+
self.assertEqual(slug1, 'and-now-with-a-tabular-inline-1234-12-07')
4510+
self.assertEqual(slug2, 'option-two-and-now-with-a-tabular-inline')
45114511

45124512
# Add an inline
45134513
# Button may be outside the browser frame.
@@ -4521,12 +4521,12 @@ def test_prepopulated_fields(self):
45214521
self.selenium.find_element_by_id('id_relatedprepopulated_set-2-1-pubdate').send_keys('1981-08-22')
45224522
self.select_option('#id_relatedprepopulated_set-2-1-status', 'option one')
45234523
self.selenium.find_element_by_id('id_relatedprepopulated_set-2-1-name').send_keys(
4524-
r'a tÃbűlaŘ inline with ignored ;"&*^\%$#@-/`~ characters'
4524+
r'tÃbűlaŘ inline with ignored ;"&*^\%$#@-/`~ characters'
45254525
)
45264526
slug1 = self.selenium.find_element_by_id('id_relatedprepopulated_set-2-1-slug1').get_attribute('value')
45274527
slug2 = self.selenium.find_element_by_id('id_relatedprepopulated_set-2-1-slug2').get_attribute('value')
4528-
self.assertEqual(slug1, 'tabular-inline-ignored-characters-1981-08-22')
4529-
self.assertEqual(slug2, 'option-one-tabular-inline-ignored-characters')
4528+
self.assertEqual(slug1, 'tabular-inline-with-ignored-characters-1981-08-22')
4529+
self.assertEqual(slug2, 'option-one-tabular-inline-with-ignored-characters')
45304530
# Add an inline without an initial inline.
45314531
# The button is outside of the browser frame.
45324532
self.selenium.execute_script("window.scrollTo(0, document.body.scrollHeight);")
@@ -4540,42 +4540,42 @@ def test_prepopulated_fields(self):
45404540
self.selenium.find_element_by_xpath('//input[@value="Save"]').click()
45414541
self.assertEqual(MainPrepopulated.objects.all().count(), 1)
45424542
MainPrepopulated.objects.get(
4543-
name=' this is the mAin nÀMë and it\'s awεšomeıııİ',
4543+
name=' the mAin nÀMë and it\'s awεšomeıııİ',
45444544
pubdate='2012-02-18',
45454545
status='option two',
4546-
slug1='main-name-and-its-awesomeiiii-2012-02-18',
4547-
slug2='option-two-main-name-and-its-awesomeiiii',
4548-
slug3='this-is-the-main-nàmë-and-its-awεšomeıııi',
4546+
slug1='the-main-name-and-its-awesomeiiii-2012-02-18',
4547+
slug2='option-two-the-main-name-and-its-awesomeiiii',
4548+
slug3='the-main-nàmë-and-its-awεšomeıııi',
45494549
)
45504550
self.assertEqual(RelatedPrepopulated.objects.all().count(), 4)
45514551
RelatedPrepopulated.objects.get(
45524552
name=' here is a sŤāÇkeð inline ! ',
45534553
pubdate='2011-12-17',
45544554
status='option one',
4555-
slug1='here-stacked-inline-2011-12-17',
4556-
slug2='option-one-here-stacked-inline',
4555+
slug1='here-is-a-stacked-inline-2011-12-17',
4556+
slug2='option-one-here-is-a-stacked-inline',
45574557
)
45584558
RelatedPrepopulated.objects.get(
45594559
# 75 characters in name field
45604560
name=' now you haVe anöther sŤāÇkeð inline with a very ... loooooooooooooooooo',
45614561
pubdate='1999-01-25',
45624562
status='option two',
4563-
slug1='now-you-have-another-stacked-inline-very-loooooooo',
4564-
slug2='option-two-now-you-have-another-stacked-inline-very-looooooo',
4563+
slug1='now-you-have-another-stacked-inline-with-a-very-lo',
4564+
slug2='option-two-now-you-have-another-stacked-inline-with-a-very-l',
45654565
)
45664566
RelatedPrepopulated.objects.get(
45674567
name='And now, with a tÃbűlaŘ inline !!!',
45684568
pubdate='1234-12-07',
45694569
status='option two',
4570-
slug1='and-now-tabular-inline-1234-12-07',
4571-
slug2='option-two-and-now-tabular-inline',
4570+
slug1='and-now-with-a-tabular-inline-1234-12-07',
4571+
slug2='option-two-and-now-with-a-tabular-inline',
45724572
)
45734573
RelatedPrepopulated.objects.get(
4574-
name=r'a tÃbűlaŘ inline with ignored ;"&*^\%$#@-/`~ characters',
4574+
name=r'tÃbűlaŘ inline with ignored ;"&*^\%$#@-/`~ characters',
45754575
pubdate='1981-08-22',
45764576
status='option one',
4577-
slug1='tabular-inline-ignored-characters-1981-08-22',
4578-
slug2='option-one-tabular-inline-ignored-characters',
4577+
slug1='tabular-inline-with-ignored-characters-1981-08-22',
4578+
slug2='option-one-tabular-inline-with-ignored-characters',
45794579
)
45804580

45814581
def test_populate_existing_object(self):
@@ -4601,8 +4601,8 @@ def test_populate_existing_object(self):
46014601
# The slugs got prepopulated since they were originally empty
46024602
slug1 = self.selenium.find_element_by_id('id_slug1').get_attribute('value')
46034603
slug2 = self.selenium.find_element_by_id('id_slug2').get_attribute('value')
4604-
self.assertEqual(slug1, 'main-name-best-2012-02-18')
4605-
self.assertEqual(slug2, 'option-two-main-name-best')
4604+
self.assertEqual(slug1, 'this-is-the-main-name-the-best-2012-02-18')
4605+
self.assertEqual(slug2, 'option-two-this-is-the-main-name-the-best')
46064606

46074607
# Save the object
46084608
with self.wait_page_loaded():
@@ -4614,8 +4614,8 @@ def test_populate_existing_object(self):
46144614
# The slugs got prepopulated didn't change since they were originally not empty
46154615
slug1 = self.selenium.find_element_by_id('id_slug1').get_attribute('value')
46164616
slug2 = self.selenium.find_element_by_id('id_slug2').get_attribute('value')
4617-
self.assertEqual(slug1, 'main-name-best-2012-02-18')
4618-
self.assertEqual(slug2, 'option-two-main-name-best')
4617+
self.assertEqual(slug1, 'this-is-the-main-name-the-best-2012-02-18')
4618+
self.assertEqual(slug2, 'option-two-this-is-the-main-name-the-best')
46194619

46204620
def test_collapsible_fieldset(self):
46214621
"""

0 commit comments

Comments
 (0)