Clean up label-embedding architecture
- Move {id,label} stripping into _SetCriterion.from_json() so both
MultiCriterion and ChoiceCriterion normalise at the parse boundary;
the querying layer stays typed (list[int] / list[str]) and clean.
- Revert MultiCriterion to a thin _extra_q() override; _SetCriterion.to_q()
is no longer duplicated.
- JS: readSearchSelect always emits {id, label} objects — no conditional
mixed-type arrays. filter_bar.js stores them as-is for all fields,
removing the fragile isIdField hardcoded list.
- Update tests to use the {id, label} filter format.
https://claude.ai/code/session_01EyAJcMoDktLrY9tSbdHViA
This commit is contained in:
@@ -94,7 +94,7 @@ class FilterBarRenderingTest(TestCase):
|
||||
|
||||
def test_game_filter_bar_roundtrips_selected_status(self):
|
||||
"""A status in filter_json renders as an include pill in the widget."""
|
||||
filter_json = json.dumps({"status": {"value": ["f"], "modifier": ""}})
|
||||
filter_json = json.dumps({"status": {"value": [{"id": "f", "label": "Finished"}], "modifier": "INCLUDES"}})
|
||||
html = str(
|
||||
FilterBar(
|
||||
filter_json=filter_json, preset_list_url="/l", preset_save_url="/s"
|
||||
|
||||
@@ -121,6 +121,15 @@ class TestMultiCriterion:
|
||||
c = MultiCriterion(value=[], modifier=Modifier.IS_NULL)
|
||||
assert c.to_q("device_id") == Q(device_id__isnull=True)
|
||||
|
||||
def test_from_json_strips_embedded_labels(self):
|
||||
"""from_json normalises {id, label} dicts to bare ids."""
|
||||
c = MultiCriterion.from_json(
|
||||
{"value": [{"id": 797, "label": "Hollow Knight"}], "excludes": [{"id": 11, "label": "Steam Deck"}]}
|
||||
)
|
||||
assert c.value == [797]
|
||||
assert c.excludes == [11]
|
||||
assert c.to_q("game_id") == Q(game_id__in=[797]) & ~Q(game_id__in=[11])
|
||||
|
||||
|
||||
class TestChoiceCriterionAgainstDB:
|
||||
"""Verify ChoiceCriterion produces correct DB results."""
|
||||
|
||||
Reference in New Issue
Block a user