Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ b1e33ceceda1e75ff68c7deed8f6659683a195d3
c9178ef17a0e1070f5a25096d8e13385d404dc92
1101467ce0756272a54f4c7bc65c4c335a94111b
6cff02078799b7c683a0d39630d49ab4fe532e7c
4286a23df64f6ce3b9b6ed097f4d1aac7d9e0de4
2 changes: 1 addition & 1 deletion django/contrib/admin/templates/admin/actions.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
{% endblock %}
{% block actions-counter %}
{% if actions_selection_counter %}
<span class="action-counter" data-actions-icnt="{{ cl.result_list|length }}">{{ selection_note }}</span>
<span class="action-counter" data-actions-icnt="{{ cl.result_list|length }}" aria-live="polite" aria-atomic="true">{{ selection_note }}</span>
{% if cl.result_count != cl.result_list|length %}
<span class="all hidden">{{ selection_note_all }}</span>
<span class="question hidden">
Expand Down
4 changes: 2 additions & 2 deletions django/db/models/fields/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -698,8 +698,8 @@ class KeyTransformIRegex(
class KeyTransformNumericLookupMixin:
def process_rhs(self, compiler, connection):
rhs, rhs_params = super().process_rhs(compiler, connection)
if not connection.features.has_native_json_field:
rhs_params = [json.loads(value) for value in rhs_params]
if not connection.features.has_native_json_field and self.rhs_is_direct_value():
rhs_params = tuple(json.loads(value) for value in rhs_params)
return rhs, rhs_params


Expand Down
10 changes: 10 additions & 0 deletions tests/admin_views/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -4646,6 +4646,16 @@ def test_changelist_input_html(self):
# 1 select per object = 3 selects
self.assertContains(response, "<select", count=4)

def test_actions_counter_is_live_region(self):
response = self.client.get(reverse("admin:admin_views_person_changelist"))
self.assertContains(
response,
(
'class="action-counter" data-actions-icnt="3" '
'aria-live="polite" aria-atomic="true"'
),
)

def test_post_messages(self):
# Ticket 12707: Saving inline editable should not show admin
# action warnings
Expand Down
29 changes: 29 additions & 0 deletions tests/model_fields/test_jsonfield.py
Original file line number Diff line number Diff line change
Expand Up @@ -1304,6 +1304,35 @@ def test_json_type_casting_with_coalesce(self):
).first()
self.assertEqual(result.coalesced_value, "This is valid JSON primitive.")

def test_numeric_lookups_with_expression(self):
obj_greater = NullableJSONModel.objects.create(
value={"target": 5, "comparison": 2}
)
obj_lesser = NullableJSONModel.objects.create(
value={"target": 2, "comparison": 5}
)
obj_equal = NullableJSONModel.objects.create(
value={"target": 2, "comparison": 2}
)
objs = [obj_greater.pk, obj_lesser.pk, obj_equal.pk]

tests = [
("gt", [obj_greater]),
("lt", [obj_lesser]),
("gte", [obj_greater, obj_equal]),
("lte", [obj_lesser, obj_equal]),
]

for lookup, expected in tests:
with self.subTest(lookup=lookup):
self.assertCountEqual(
NullableJSONModel.objects.filter(
id__in=objs,
**{f"value__target__{lookup}": F("value__comparison")},
),
expected,
)


@skipUnlessDBFeature("supports_primitives_in_json_field")
class JSONNullTests(TestCase):
Expand Down
Loading