mirror of https://github.com/django/django.git
Fixed #34025 -- Fixed selecting ModelAdmin.autocomplete_fields after adding/changing related instances via popups.
Regression in c72f6f36c1
.
Thanks Alexandre da Silva for the report.
This commit is contained in:
parent
6e891a1722
commit
9976f3d4b8
|
@ -96,7 +96,8 @@
|
||||||
// Extract the model from the popup url '.../<model>/add/' or
|
// Extract the model from the popup url '.../<model>/add/' or
|
||||||
// '.../<model>/<id>/change/' depending the action (add or change).
|
// '.../<model>/<id>/change/' depending the action (add or change).
|
||||||
const modelName = path.split('/')[path.split('/').length - (objId ? 4 : 3)];
|
const modelName = path.split('/')[path.split('/').length - (objId ? 4 : 3)];
|
||||||
const selectsRelated = document.querySelectorAll(`[data-model-ref="${modelName}"] select`);
|
// Exclude autocomplete selects.
|
||||||
|
const selectsRelated = document.querySelectorAll(`[data-model-ref="${modelName}"] select:not(.admin-autocomplete)`);
|
||||||
|
|
||||||
selectsRelated.forEach(function(select) {
|
selectsRelated.forEach(function(select) {
|
||||||
if (currentSelect === select) {
|
if (currentSelect === select) {
|
||||||
|
|
|
@ -23,3 +23,7 @@ Bugfixes
|
||||||
* Fixed a regression in Django 4.1 that caused a
|
* Fixed a regression in Django 4.1 that caused a
|
||||||
``QuerySet.values()/values_list()`` crash on ``ArrayAgg()`` and
|
``QuerySet.values()/values_list()`` crash on ``ArrayAgg()`` and
|
||||||
``JSONBAgg()`` (:ticket:`34016`).
|
``JSONBAgg()`` (:ticket:`34016`).
|
||||||
|
|
||||||
|
* Fixed a bug in Django 4.1 that caused :attr:`.ModelAdmin.autocomplete_fields`
|
||||||
|
to be incorrectly selected after adding/changing related instances via popups
|
||||||
|
(:ticket:`34025`).
|
||||||
|
|
|
@ -1165,6 +1165,14 @@ class GetFormsetsArgumentCheckingAdmin(admin.ModelAdmin):
|
||||||
return super().get_formsets_with_inlines(request, obj)
|
return super().get_formsets_with_inlines(request, obj)
|
||||||
|
|
||||||
|
|
||||||
|
class CountryAdmin(admin.ModelAdmin):
|
||||||
|
search_fields = ["name"]
|
||||||
|
|
||||||
|
|
||||||
|
class TravelerAdmin(admin.ModelAdmin):
|
||||||
|
autocomplete_fields = ["living_country"]
|
||||||
|
|
||||||
|
|
||||||
site = admin.AdminSite(name="admin")
|
site = admin.AdminSite(name="admin")
|
||||||
site.site_url = "/my-site-url/"
|
site.site_url = "/my-site-url/"
|
||||||
site.register(Article, ArticleAdmin)
|
site.register(Article, ArticleAdmin)
|
||||||
|
@ -1286,8 +1294,8 @@ site.register(ExplicitlyProvidedPK, GetFormsetsArgumentCheckingAdmin)
|
||||||
site.register(ImplicitlyGeneratedPK, GetFormsetsArgumentCheckingAdmin)
|
site.register(ImplicitlyGeneratedPK, GetFormsetsArgumentCheckingAdmin)
|
||||||
site.register(UserProxy)
|
site.register(UserProxy)
|
||||||
site.register(Box)
|
site.register(Box)
|
||||||
site.register(Country)
|
site.register(Country, CountryAdmin)
|
||||||
site.register(Traveler)
|
site.register(Traveler, TravelerAdmin)
|
||||||
|
|
||||||
# Register core models we need in our tests
|
# Register core models we need in our tests
|
||||||
site.register(User, UserAdmin)
|
site.register(User, UserAdmin)
|
||||||
|
|
|
@ -6317,18 +6317,24 @@ class SeleniumTests(AdminSeleniumTestCase):
|
||||||
finally:
|
finally:
|
||||||
self.selenium.set_window_size(current_size["width"], current_size["height"])
|
self.selenium.set_window_size(current_size["width"], current_size["height"])
|
||||||
|
|
||||||
def test_updating_related_objects_updates_fk_selects(self):
|
def test_updating_related_objects_updates_fk_selects_except_autocompletes(self):
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
from selenium.webdriver.support.ui import Select
|
from selenium.webdriver.support.ui import Select
|
||||||
|
|
||||||
born_country_select_id = "id_born_country"
|
born_country_select_id = "id_born_country"
|
||||||
living_country_select_id = "id_living_country"
|
living_country_select_id = "id_living_country"
|
||||||
|
living_country_select2_textbox_id = "select2-id_living_country-container"
|
||||||
favorite_country_to_vacation_select_id = "id_favorite_country_to_vacation"
|
favorite_country_to_vacation_select_id = "id_favorite_country_to_vacation"
|
||||||
continent_select_id = "id_continent"
|
continent_select_id = "id_continent"
|
||||||
|
|
||||||
def _get_HTML_inside_element_by_id(id_):
|
def _get_HTML_inside_element_by_id(id_):
|
||||||
return self.selenium.find_element(By.ID, id_).get_attribute("innerHTML")
|
return self.selenium.find_element(By.ID, id_).get_attribute("innerHTML")
|
||||||
|
|
||||||
|
def _get_text_inside_element_by_selector(selector):
|
||||||
|
return self.selenium.find_element(By.CSS_SELECTOR, selector).get_attribute(
|
||||||
|
"innerText"
|
||||||
|
)
|
||||||
|
|
||||||
self.admin_login(
|
self.admin_login(
|
||||||
username="super", password="secret", login_url=reverse("admin:index")
|
username="super", password="secret", login_url=reverse("admin:index")
|
||||||
)
|
)
|
||||||
|
@ -6353,12 +6359,16 @@ class SeleniumTests(AdminSeleniumTestCase):
|
||||||
<option value="1" selected="">Argentina</option>
|
<option value="1" selected="">Argentina</option>
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
self.assertHTMLEqual(
|
# Argentina isn't added to the living_country select nor selected by
|
||||||
_get_HTML_inside_element_by_id(living_country_select_id),
|
# the select2 widget.
|
||||||
"""
|
self.assertEqual(
|
||||||
<option value="" selected="">---------</option>
|
_get_text_inside_element_by_selector(f"#{living_country_select_id}"), ""
|
||||||
<option value="1">Argentina</option>
|
)
|
||||||
""",
|
self.assertEqual(
|
||||||
|
_get_text_inside_element_by_selector(
|
||||||
|
f"#{living_country_select2_textbox_id}"
|
||||||
|
),
|
||||||
|
"",
|
||||||
)
|
)
|
||||||
# Argentina won't appear because favorite_country_to_vacation field has
|
# Argentina won't appear because favorite_country_to_vacation field has
|
||||||
# limit_choices_to.
|
# limit_choices_to.
|
||||||
|
@ -6386,13 +6396,18 @@ class SeleniumTests(AdminSeleniumTestCase):
|
||||||
<option value="2">Spain</option>
|
<option value="2">Spain</option>
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
self.assertHTMLEqual(
|
|
||||||
_get_HTML_inside_element_by_id(living_country_select_id),
|
# Spain is added to the living_country select and it's also selected by
|
||||||
"""
|
# the select2 widget.
|
||||||
<option value="" selected="">---------</option>
|
self.assertEqual(
|
||||||
<option value="1">Argentina</option>
|
_get_text_inside_element_by_selector(f"#{living_country_select_id} option"),
|
||||||
<option value="2" selected="">Spain</option>
|
"Spain",
|
||||||
""",
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
_get_text_inside_element_by_selector(
|
||||||
|
f"#{living_country_select2_textbox_id}"
|
||||||
|
),
|
||||||
|
"Spain",
|
||||||
)
|
)
|
||||||
# Spain won't appear because favorite_country_to_vacation field has
|
# Spain won't appear because favorite_country_to_vacation field has
|
||||||
# limit_choices_to.
|
# limit_choices_to.
|
||||||
|
@ -6422,13 +6437,17 @@ class SeleniumTests(AdminSeleniumTestCase):
|
||||||
<option value="2">Italy</option>
|
<option value="2">Italy</option>
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
self.assertHTMLEqual(
|
# Italy is added to the living_country select and it's also selected by
|
||||||
_get_HTML_inside_element_by_id(living_country_select_id),
|
# the select2 widget.
|
||||||
"""
|
self.assertEqual(
|
||||||
<option value="" selected="">---------</option>
|
_get_text_inside_element_by_selector(f"#{living_country_select_id} option"),
|
||||||
<option value="1">Argentina</option>
|
"Italy",
|
||||||
<option value="2" selected="">Italy</option>
|
)
|
||||||
""",
|
self.assertEqual(
|
||||||
|
_get_text_inside_element_by_selector(
|
||||||
|
f"#{living_country_select2_textbox_id}"
|
||||||
|
),
|
||||||
|
"Italy",
|
||||||
)
|
)
|
||||||
# favorite_country_to_vacation field has no options.
|
# favorite_country_to_vacation field has no options.
|
||||||
self.assertHTMLEqual(
|
self.assertHTMLEqual(
|
||||||
|
|
Loading…
Reference in New Issue