Skip to content

Commit 9531b1b

Browse files
cgh ! use p_code for display and id for persistence in AdminAreas choices (#102)
1 parent 4776a26 commit 9531b1b

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

src/country_workspace/contrib/hope/geo.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class AdminLevelChoice(APIChoicesMixin, ChildFieldMixin, forms.ChoiceField):
6464

6565
def __init__(self, **kwargs: Any) -> None:
6666
super().__init__(**kwargs)
67+
self.id_to_code, self.code_to_id = {}, {}
6768
self.choices = self.get_choices_for_parent_value(parent_value=state.tenant.slug)
6869

6970
def validate_with_parent(self, parent_value: Any, value: Any) -> None:
@@ -81,11 +82,23 @@ def get_choices_for_parent_value(
8182
or not (filtered := self._filter_by_area_types(data, valid_types))
8283
):
8384
return [] if only_codes else [("", "")]
85+
86+
self.code_to_id = {r["p_code"]: str(r["id"]) for r in filtered}
87+
self.id_to_code = {v: k for k, v in self.code_to_id.items()}
88+
8489
return {
85-
True: [r["p_code"] for r in filtered],
90+
True: list(self.id_to_code),
8691
False: [("", ""), *[(r["p_code"], f"{r['p_code']} - {r['name']}") for r in filtered]],
8792
}[only_codes]
8893

94+
def prepare_value(self, value: Any) -> str | None:
95+
val = super().prepare_value(value)
96+
return self.id_to_code.get(str(val), val)
97+
98+
def to_python(self, value: Any) -> str | None:
99+
val = self.code_to_id.get(value, value)
100+
return super().to_python(val)
101+
89102
def _get_valid_area_types(self) -> set[Any]:
90103
key = f"area_types_level_{self.level}"
91104
if (types := cache_manager.retrieve(key)) is None:

tests/contrib/hope/test_geo.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"previous": None,
3434
"results": [
3535
{
36+
"id": str(uuid4()),
3637
"name": "Kyivska",
3738
"p_code": "UA32",
3839
"area_type": str(uuid4()),
@@ -83,7 +84,9 @@ def test_admin_level_choice_validate(
8384
country_field = FlexFieldFactory(name="country", definition=fd1, fieldset=fs)
8485
FlexFieldFactory(name="region", definition=fd2, fieldset=fs, master=country_field)
8586

86-
errors = fs.validate([{"country": "UA", "region": "UA32"}])
87+
country = COUNTRY["results"][0]["iso_code2"]
88+
area_id = ADMIN1_UA["results"][0]["id"]
89+
errors = fs.validate([{"country": country, "region": area_id}])
8790
assert errors == {}
8891

8992
errors = fs.validate([{"country": office.slug, "region": "---"}])
@@ -173,3 +176,27 @@ def test_admin_level_choice_cached_data(
173176

174177
assert fetched == cached_data
175178
mock_get.assert_not_called()
179+
180+
181+
@override_config(HOPE_API_URL="https://fake-hope.org/api/rest/")
182+
def test_admin_level_choice_prepare_value(
183+
db,
184+
mocker: MockerFixture,
185+
mocked_responses: RequestsMock,
186+
office: "Office",
187+
mock_area_type: mock.Mock,
188+
mock_cache: mock.Mock,
189+
):
190+
mocker.patch("country_workspace.contrib.hope.geo.state.tenant", office)
191+
mocked_responses.add(
192+
mocked_responses.GET,
193+
f"https://fake-hope.org/api/rest/{office.slug}/geo/areas/",
194+
json=ADMIN1_UA,
195+
)
196+
197+
field = Admin1Choice()
198+
rec = ADMIN1_UA["results"][0]
199+
200+
assert field.prepare_value(rec["id"]) == rec["p_code"]
201+
assert field.prepare_value(rec["p_code"]) == rec["p_code"]
202+
assert field.prepare_value("UNKNOWN") == "UNKNOWN"

0 commit comments

Comments
 (0)