mirror of https://github.com/django/django.git
Refs #12990 -- Added DatabaseFeatures.has_json_operators.
CockroachDB also has them.
This commit is contained in:
parent
d00e034a28
commit
f59a2b7306
|
@ -309,6 +309,8 @@ class BaseDatabaseFeatures:
|
||||||
supports_primitives_in_json_field = True
|
supports_primitives_in_json_field = True
|
||||||
# Is there a true datatype for JSON?
|
# Is there a true datatype for JSON?
|
||||||
has_native_json_field = False
|
has_native_json_field = False
|
||||||
|
# Does the backend use PostgreSQL-style JSON operators like '->'?
|
||||||
|
has_json_operators = False
|
||||||
|
|
||||||
def __init__(self, connection):
|
def __init__(self, connection):
|
||||||
self.connection = connection
|
self.connection = connection
|
||||||
|
|
|
@ -58,6 +58,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||||
supported_explain_formats = {'JSON', 'TEXT', 'XML', 'YAML'}
|
supported_explain_formats = {'JSON', 'TEXT', 'XML', 'YAML'}
|
||||||
validates_explain_options = False # A query will error on invalid options.
|
validates_explain_options = False # A query will error on invalid options.
|
||||||
supports_deferrable_unique_constraints = True
|
supports_deferrable_unique_constraints = True
|
||||||
|
has_json_operators = True
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def is_postgresql_10(self):
|
def is_postgresql_10(self):
|
||||||
|
|
|
@ -17,7 +17,9 @@ from django.db.models.fields.json import (
|
||||||
KeyTransformTextLookupMixin,
|
KeyTransformTextLookupMixin,
|
||||||
)
|
)
|
||||||
from django.db.models.functions import Cast
|
from django.db.models.functions import Cast
|
||||||
from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
|
from django.test import (
|
||||||
|
SimpleTestCase, TestCase, skipIfDBFeature, skipUnlessDBFeature,
|
||||||
|
)
|
||||||
from django.test.utils import CaptureQueriesContext
|
from django.test.utils import CaptureQueriesContext
|
||||||
|
|
||||||
from .models import CustomJSONDecoder, JSONModel, NullableJSONModel
|
from .models import CustomJSONDecoder, JSONModel, NullableJSONModel
|
||||||
|
@ -607,7 +609,7 @@ class TestQuerying(TestCase):
|
||||||
def test_key_iregex(self):
|
def test_key_iregex(self):
|
||||||
self.assertIs(NullableJSONModel.objects.filter(value__foo__iregex=r'^bAr$').exists(), True)
|
self.assertIs(NullableJSONModel.objects.filter(value__foo__iregex=r'^bAr$').exists(), True)
|
||||||
|
|
||||||
@skipUnless(connection.vendor == 'postgresql', 'kwargs are crafted for PostgreSQL.')
|
@skipUnlessDBFeature('has_json_operators')
|
||||||
def test_key_sql_injection(self):
|
def test_key_sql_injection(self):
|
||||||
with CaptureQueriesContext(connection) as queries:
|
with CaptureQueriesContext(connection) as queries:
|
||||||
self.assertIs(
|
self.assertIs(
|
||||||
|
@ -621,7 +623,7 @@ class TestQuerying(TestCase):
|
||||||
queries[0]['sql'],
|
queries[0]['sql'],
|
||||||
)
|
)
|
||||||
|
|
||||||
@skipIf(connection.vendor == 'postgresql', 'PostgreSQL uses operators not functions.')
|
@skipIfDBFeature('has_json_operators')
|
||||||
def test_key_sql_injection_escape(self):
|
def test_key_sql_injection_escape(self):
|
||||||
query = str(JSONModel.objects.filter(**{
|
query = str(JSONModel.objects.filter(**{
|
||||||
"""value__test") = '"a"' OR 1 = 1 OR ("d""": 'x',
|
"""value__test") = '"a"' OR 1 = 1 OR ("d""": 'x',
|
||||||
|
|
Loading…
Reference in New Issue