1
0
mirror of https://github.com/django/django.git synced 2025-10-31 09:41:08 +00:00

Fixed #11803 -- Allowed admin select widgets to display new related objects.

Adjusted admin javascript to add newly created related objects to
already loaded select widgets.

In this version, applies only where limit_choices_to is not set.
This commit is contained in:
mgaligniana
2022-04-13 15:27:21 +02:00
committed by Mariusz Felisiak
parent deedf5bbc3
commit c72f6f36c1
7 changed files with 216 additions and 3 deletions

View File

@@ -44,6 +44,7 @@ from .models import (
Color,
Color2,
ComplexSortedPerson,
Country,
CoverLetter,
CustomArticle,
CyclicOne,
@@ -126,6 +127,7 @@ from .models import (
Telegram,
Thing,
Topping,
Traveler,
UnchangeableObject,
UndeletableObject,
UnorderedObject,
@@ -1284,6 +1286,8 @@ site.register(ExplicitlyProvidedPK, GetFormsetsArgumentCheckingAdmin)
site.register(ImplicitlyGeneratedPK, GetFormsetsArgumentCheckingAdmin)
site.register(UserProxy)
site.register(Box)
site.register(Country)
site.register(Traveler)
# Register core models we need in our tests
site.register(User, UserAdmin)

View File

@@ -1098,3 +1098,39 @@ class Box(models.Model):
next_box = models.ForeignKey(
"self", null=True, on_delete=models.SET_NULL, blank=True
)
class Country(models.Model):
NORTH_AMERICA = "North America"
SOUTH_AMERICA = "South America"
EUROPE = "Europe"
ASIA = "Asia"
OCEANIA = "Oceania"
ANTARCTICA = "Antarctica"
CONTINENT_CHOICES = [
(NORTH_AMERICA, NORTH_AMERICA),
(SOUTH_AMERICA, SOUTH_AMERICA),
(EUROPE, EUROPE),
(ASIA, ASIA),
(OCEANIA, OCEANIA),
(ANTARCTICA, ANTARCTICA),
]
name = models.CharField(max_length=80)
continent = models.CharField(max_length=13, choices=CONTINENT_CHOICES)
def __str__(self):
return self.name
class Traveler(models.Model):
born_country = models.ForeignKey(Country, models.CASCADE)
living_country = models.ForeignKey(
Country, models.CASCADE, related_name="living_country_set"
)
favorite_country_to_vacation = models.ForeignKey(
Country,
models.CASCADE,
related_name="favorite_country_to_vacation_set",
limit_choices_to={"continent": Country.ASIA},
)

View File

@@ -134,6 +134,7 @@ from .models import (
Telegram,
TitleTranslation,
Topping,
Traveler,
UnchangeableObject,
UndeletableObject,
UnorderedObject,
@@ -6275,6 +6276,146 @@ class SeleniumTests(AdminSeleniumTestCase):
finally:
self.selenium.set_window_size(current_size["width"], current_size["height"])
def test_updating_related_objects_updates_fk_selects(self):
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
born_country_select_id = "id_born_country"
living_country_select_id = "id_living_country"
favorite_country_to_vacation_select_id = "id_favorite_country_to_vacation"
continent_select_id = "id_continent"
def _get_HTML_inside_element_by_id(id_):
return self.selenium.find_element(By.ID, id_).get_attribute("innerHTML")
self.admin_login(
username="super", password="secret", login_url=reverse("admin:index")
)
add_url = reverse("admin:admin_views_traveler_add")
self.selenium.get(self.live_server_url + add_url)
# Add new Country from the born_country select.
self.selenium.find_element(By.ID, f"add_{born_country_select_id}").click()
self.wait_for_and_switch_to_popup()
self.selenium.find_element(By.ID, "id_name").send_keys("Argentina")
continent_select = Select(
self.selenium.find_element(By.ID, continent_select_id)
)
continent_select.select_by_visible_text("South America")
self.selenium.find_element(By.CSS_SELECTOR, '[type="submit"]').click()
self.selenium.switch_to.window(self.selenium.window_handles[0])
self.assertHTMLEqual(
_get_HTML_inside_element_by_id(born_country_select_id),
"""
<option value="" selected="">---------</option>
<option value="1" selected="">Argentina</option>
""",
)
self.assertHTMLEqual(
_get_HTML_inside_element_by_id(living_country_select_id),
"""
<option value="" selected="">---------</option>
<option value="1">Argentina</option>
""",
)
# Argentina won't appear because favorite_country_to_vacation field has
# limit_choices_to.
self.assertHTMLEqual(
_get_HTML_inside_element_by_id(favorite_country_to_vacation_select_id),
'<option value="" selected="">---------</option>',
)
# Add new Country from the living_country select.
self.selenium.find_element(By.ID, f"add_{living_country_select_id}").click()
self.wait_for_and_switch_to_popup()
self.selenium.find_element(By.ID, "id_name").send_keys("Spain")
continent_select = Select(
self.selenium.find_element(By.ID, continent_select_id)
)
continent_select.select_by_visible_text("Europe")
self.selenium.find_element(By.CSS_SELECTOR, '[type="submit"]').click()
self.selenium.switch_to.window(self.selenium.window_handles[0])
self.assertHTMLEqual(
_get_HTML_inside_element_by_id(born_country_select_id),
"""
<option value="" selected="">---------</option>
<option value="1" selected="">Argentina</option>
<option value="2">Spain</option>
""",
)
self.assertHTMLEqual(
_get_HTML_inside_element_by_id(living_country_select_id),
"""
<option value="" selected="">---------</option>
<option value="1">Argentina</option>
<option value="2" selected="">Spain</option>
""",
)
# Spain won't appear because favorite_country_to_vacation field has
# limit_choices_to.
self.assertHTMLEqual(
_get_HTML_inside_element_by_id(favorite_country_to_vacation_select_id),
'<option value="" selected="">---------</option>',
)
# Edit second Country created from living_country select.
favorite_select = Select(
self.selenium.find_element(By.ID, living_country_select_id)
)
favorite_select.select_by_visible_text("Spain")
self.selenium.find_element(By.ID, f"change_{living_country_select_id}").click()
self.wait_for_and_switch_to_popup()
favorite_name_input = self.selenium.find_element(By.ID, "id_name")
favorite_name_input.clear()
favorite_name_input.send_keys("Italy")
self.selenium.find_element(By.CSS_SELECTOR, '[type="submit"]').click()
self.selenium.switch_to.window(self.selenium.window_handles[0])
self.assertHTMLEqual(
_get_HTML_inside_element_by_id(born_country_select_id),
"""
<option value="" selected="">---------</option>
<option value="1" selected="">Argentina</option>
<option value="2">Italy</option>
""",
)
self.assertHTMLEqual(
_get_HTML_inside_element_by_id(living_country_select_id),
"""
<option value="" selected="">---------</option>
<option value="1">Argentina</option>
<option value="2" selected="">Italy</option>
""",
)
# favorite_country_to_vacation field has no options.
self.assertHTMLEqual(
_get_HTML_inside_element_by_id(favorite_country_to_vacation_select_id),
'<option value="" selected="">---------</option>',
)
# Add a new Asian country.
self.selenium.find_element(
By.ID, f"add_{favorite_country_to_vacation_select_id}"
).click()
self.wait_for_and_switch_to_popup()
favorite_name_input = self.selenium.find_element(By.ID, "id_name")
favorite_name_input.send_keys("Qatar")
continent_select = Select(
self.selenium.find_element(By.ID, continent_select_id)
)
continent_select.select_by_visible_text("Asia")
self.selenium.find_element(By.CSS_SELECTOR, '[type="submit"]').click()
self.selenium.switch_to.window(self.selenium.window_handles[0])
# Submit the new Traveler.
self.selenium.find_element(By.CSS_SELECTOR, '[name="_save"]').click()
traveler = Traveler.objects.get()
self.assertEqual(traveler.born_country.name, "Argentina")
self.assertEqual(traveler.living_country.name, "Italy")
self.assertEqual(traveler.favorite_country_to_vacation.name, "Qatar")
@override_settings(ROOT_URLCONF="admin_views.urls")
class ReadonlyTest(AdminFieldExtractionMixin, TestCase):