Repository: django/django
File: tests/model_fields/test_jsonfield.py (Python)

Code before:
        obj2.value = JSONNull()
        NullableJSONModel.objects.bulk_update([obj1, obj2], fields=["value"])
        self.assertSequenceEqual(
            NullableJSONModel.objects.filter(value=JSONNull()),
            [obj1, obj2],
        )

    def test_case_expression_with_jsonnull_then(self):
        obj = JSONModel.objects.create(value={"key": "value"})
        JSONModel.objects.filter(pk=obj.pk).update(
            value=Case(
                When(value={"key": "value"}, then=JSONNull()),
            )
        )
        obj.refresh_from_db()
        self.assertIsNone(obj.value)

    def test_case_expr_with_jsonnull_condition(self):
        obj = NullableJSONModel.objects.create(value=JSONNull())
        NullableJSONModel.objects.filter(pk=obj.pk).update(
            value=Case(
                When(
                    value=JSONNull(),
                    then=Value({"key": "replaced"}, output_field=JSONField()),
                )
            ),
        )
        obj.refresh_from_db()
        self.assertEqual(obj.value, {"key": "replaced"})

    def test_key_transform_exact_filter(self):
        obj = NullableJSONModel.objects.create(value={"key": None})
        self.assertSequenceEqual(
            NullableJSONModel.objects.filter(value__key=JSONNull()),
            [obj],
        )
        self.assertSequenceEqual(
            NullableJSONModel.objects.filter(value__key=None), [obj]
        )

    def test_index_lookup(self):
        obj = NullableJSONModel.objects.create(value=["a", "b", None, 3])
        self.assertSequenceEqual(
            NullableJSONModel.objects.filter(value__2=JSONNull()), [obj]
        )
        self.assertSequenceEqual(NullableJSONModel.objects.filter(value__2=None), [obj])

    @skipUnlessDBFeature("supports_table_check_constraints")
    def test_constraint_validation(self):
        constraint = CheckConstraint(
            condition=~Q(value=JSONNull()), name="check_not_json_null"

Review comment (suggestion):
Playing with this test case (using `In()` rather than `__in`) revealed ticket-36787, but we don't have to block on that here.

Code after:

    def test_create(self):
        obj = JSONModel.objects.create(value=JSONNull())
        self.assertIsNone(obj.value)

    def test_update(self):
        obj = JSONModel.objects.create(value={"key": "value"})
        JSONModel.objects.update(value=JSONNull())
        obj.refresh_from_db()
        self.assertIsNone(obj.value)

    def test_filter(self):
        json_null = NullableJSONModel.objects.create(value=JSONNull())
        sql_null = NullableJSONModel.objects.create(value=None)
        self.assertSequenceEqual(
            [json_null], NullableJSONModel.objects.filter(value=JSONNull())
        )
        self.assertSequenceEqual(
            NullableJSONModel.objects.filter(value__isnull=True), [sql_null]
        )

    def test_filter_in(self):
        obj = NullableJSONModel.objects.create(value=JSONNull())
        obj2 = NullableJSONModel.objects.create(value=[1])
        self.assertSequenceEqual(
            NullableJSONModel.objects.filter(value__in=[JSONNull(), [1], "foo"]),
            [obj, obj2],
        )

    def test_key_in(self):
        obj1 = NullableJSONModel.objects.create(value={"key": None})
        obj2 = NullableJSONModel.objects.create(value={"key": [1]})
        self.assertSequenceEqual(
            NullableJSONModel.objects.filter(value__key__in=[JSONNull(), [1], 0]),
            [obj1, obj2],
        )

    def test_bulk_update(self):
        obj1 = NullableJSONModel.objects.create(value={"k": "1st"})
        obj2 = NullableJSONModel.objects.create(value={"k": "2nd"})
        obj1.value = JSONNull()
        obj2.value = JSONNull()
        NullableJSONModel.objects.bulk_update([obj1, obj2], fields=["value"])
        self.assertSequenceEqual(
            NullableJSONModel.objects.filter(value=JSONNull()),
            [obj1, obj2],
        )

    def test_case_expression_with_jsonnull_then(self):
        obj = JSONModel.objects.create(value={"key": "value"})
        JSONModel.objects.filter(pk=obj.pk).update(