-
-
Notifications
You must be signed in to change notification settings - Fork 32k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixed #35718 -- Add JSONArray to django.db.models.functions.
- Loading branch information
1 parent
c4c0762
commit 93f9847
Showing
5 changed files
with
295 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
from django.db import NotSupportedError | ||
from django.db.models import F, Value | ||
from django.db.models.functions import JSONArray, Lower | ||
from django.test import TestCase | ||
from django.test.testcases import skipIfDBFeature, skipUnlessDBFeature | ||
from django.utils import timezone | ||
|
||
from ..models import Article, Author | ||
|
||
|
||
@skipUnlessDBFeature("has_json_object_function") | ||
class JSONArrayTests(TestCase): | ||
@classmethod | ||
def setUpTestData(cls): | ||
Author.objects.bulk_create( | ||
[ | ||
Author(name="Ivan Ivanov", alias="iivanov"), | ||
Author(name="Bertha Berthy", alias="bberthy"), | ||
] | ||
) | ||
|
||
def test_empty(self): | ||
obj = Author.objects.annotate(json_array=JSONArray()).first() | ||
self.assertEqual(obj.json_array, []) | ||
|
||
def test_basic(self): | ||
obj = Author.objects.annotate( | ||
json_array=JSONArray(Value("name"), F("name")) | ||
).first() | ||
self.assertEqual(obj.json_array, ["name", "Ivan Ivanov"]) | ||
|
||
def test_expressions(self): | ||
obj = Author.objects.annotate( | ||
json_array=JSONArray( | ||
Lower("name"), | ||
F("alias"), | ||
F("goes_by"), | ||
Value(30000.15), | ||
F("age") * 2, | ||
) | ||
).first() | ||
self.assertEqual( | ||
obj.json_array, | ||
[ | ||
"ivan ivanov", | ||
"iivanov", | ||
None, | ||
30000.15, | ||
60, | ||
], | ||
) | ||
|
||
def test_nested_json_array(self): | ||
obj = Author.objects.annotate( | ||
json_array=JSONArray( | ||
F("name"), | ||
JSONArray(F("alias"), F("age")), | ||
) | ||
).first() | ||
self.assertEqual( | ||
obj.json_array, | ||
[ | ||
"Ivan Ivanov", | ||
["iivanov", 30], | ||
], | ||
) | ||
|
||
def test_nested_empty_json_array(self): | ||
obj = Author.objects.annotate( | ||
json_array=JSONArray( | ||
F("name"), | ||
JSONArray(), | ||
) | ||
).first() | ||
self.assertEqual( | ||
obj.json_array, | ||
[ | ||
"Ivan Ivanov", | ||
[], | ||
], | ||
) | ||
|
||
def test_textfield(self): | ||
Article.objects.create( | ||
title="The Title", | ||
text="x" * 4000, | ||
written=timezone.now(), | ||
) | ||
obj = Article.objects.annotate(json_array=JSONArray(F("text"))).first() | ||
self.assertEqual(obj.json_array, ["x" * 4000]) | ||
|
||
def test_order_by_key(self): | ||
qs = Author.objects.annotate(arr=JSONArray(F("alias"))).order_by("arr__0") | ||
self.assertQuerySetEqual(qs, Author.objects.order_by("alias")) | ||
|
||
def test_order_by_nested_key(self): | ||
qs = Author.objects.annotate(arr=JSONArray(JSONArray(F("alias")))).order_by( | ||
"-arr__0__0" | ||
) | ||
self.assertQuerySetEqual(qs, Author.objects.order_by("-alias")) | ||
|
||
|
||
@skipIfDBFeature("has_json_object_function") | ||
class JSONObjectNotSupportedTests(TestCase): | ||
def test_not_supported(self): | ||
msg = "JSONArray() is not supported on this database backend." | ||
with self.assertRaisesMessage(NotSupportedError, msg): | ||
Author.objects.annotate(json_array=JSONArray()).get() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
from django.db.models import F | ||
from django.db.models.functions import JSONArray, JSONObject | ||
from django.test import TestCase | ||
from django.test.testcases import skipUnlessDBFeature | ||
|
||
from ..models import Author | ||
|
||
|
||
@skipUnlessDBFeature("has_json_object_function") | ||
class JSONArrayObjectTests(TestCase): | ||
@classmethod | ||
def setUpTestData(cls): | ||
Author.objects.bulk_create( | ||
[ | ||
Author(name="Ivan Ivanov", alias="iivanov"), | ||
Author(name="Bertha Berthy", alias="bberthy"), | ||
] | ||
) | ||
|
||
def test_nested_json_array_object(self): | ||
obj = Author.objects.annotate( | ||
json_array=JSONArray( | ||
JSONObject( | ||
name1="name", | ||
nested_json_object1=JSONObject( | ||
alias1="alias", | ||
age1="age", | ||
), | ||
), | ||
JSONObject( | ||
name2="name", | ||
nested_json_object2=JSONObject( | ||
alias2="alias", | ||
age2="age", | ||
), | ||
), | ||
) | ||
).first() | ||
self.assertEqual( | ||
obj.json_array, | ||
[ | ||
{ | ||
"name1": "Ivan Ivanov", | ||
"nested_json_object1": { | ||
"alias1": "iivanov", | ||
"age1": 30, | ||
}, | ||
}, | ||
{ | ||
"name2": "Ivan Ivanov", | ||
"nested_json_object2": { | ||
"alias2": "iivanov", | ||
"age2": 30, | ||
}, | ||
}, | ||
], | ||
) | ||
|
||
def test_nested_json_object_array(self): | ||
obj = Author.objects.annotate( | ||
json_object=JSONObject( | ||
name="name", | ||
nested_json_array=JSONArray( | ||
JSONObject( | ||
alias1="alias", | ||
age1="age", | ||
), | ||
JSONObject( | ||
alias2="alias", | ||
age2="age", | ||
), | ||
), | ||
) | ||
).first() | ||
self.assertEqual( | ||
obj.json_object, | ||
{ | ||
"name": "Ivan Ivanov", | ||
"nested_json_array": [ | ||
{ | ||
"alias1": "iivanov", | ||
"age1": 30, | ||
}, | ||
{ | ||
"alias2": "iivanov", | ||
"age2": 30, | ||
}, | ||
], | ||
}, | ||
) | ||
|
||
def test_order_by_nested_key(self): | ||
qs = Author.objects.annotate( | ||
arr=JSONArray(JSONObject(alias=F("alias"))) | ||
).order_by("-arr__0__alias") | ||
self.assertQuerySetEqual(qs, Author.objects.order_by("-alias")) |