diff --git a/django/db/backends/base/features.py b/django/db/backends/base/features.py index 6847a6fe84..4639f1bb2e 100644 --- a/django/db/backends/base/features.py +++ b/django/db/backends/base/features.py @@ -298,6 +298,9 @@ class BaseDatabaseFeatures: # Does the backend support __contains and __contained_by lookups for # a JSONField? supports_json_field_contains = True + # Does value__d__contains={'f': 'g'} (without a list around the dict) match + # {'d': [{'f': 'g'}]}? + json_key_contains_list_matching_requires_list = False def __init__(self, connection): self.connection = connection diff --git a/django/db/backends/postgresql/features.py b/django/db/backends/postgresql/features.py index 864bcf3919..df16691444 100644 --- a/django/db/backends/postgresql/features.py +++ b/django/db/backends/postgresql/features.py @@ -57,6 +57,7 @@ class DatabaseFeatures(BaseDatabaseFeatures): validates_explain_options = False # A query will error on invalid options. supports_deferrable_unique_constraints = True has_json_operators = True + json_key_contains_list_matching_requires_list = True @cached_property def introspected_field_types(self): diff --git a/tests/model_fields/test_jsonfield.py b/tests/model_fields/test_jsonfield.py index 11e82c5998..a7648711ac 100644 --- a/tests/model_fields/test_jsonfield.py +++ b/tests/model_fields/test_jsonfield.py @@ -714,8 +714,9 @@ class TestQuerying(TestCase): )), ), ] - # PostgreSQL requires a layer of nesting. - if connection.vendor != 'postgresql': + # For databases where {'f': 'g'} (without surrounding []) matches + # [{'f': 'g'}]. + if not connection.features.json_key_contains_list_matching_requires_list: tests.append(('value__d__contains', {'f': 'g'})) for lookup, value in tests: with self.subTest(lookup=lookup, value=value):