IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
|
|
|
64 | 64 | JSONField.register_lookup(lookups.HasKey) |
65 | 65 | JSONField.register_lookup(lookups.HasKeys) |
66 | 66 | JSONField.register_lookup(lookups.HasAnyKeys) |
| 67 | JSONField.register_lookup(lookups.JSONIsNull) |
| 68 | JSONField.register_lookup(lookups.JSONExact) |
67 | 69 | |
68 | 70 | |
69 | 71 | class KeyTransform(Transform): |
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
|
|
|
1 | 1 | from django.db.models import Lookup, Transform |
| 2 | from django.db.models.lookups import IsNull, Exact |
2 | 3 | |
3 | 4 | |
4 | 5 | class PostgresSimpleLookup(Lookup): |
… |
… |
|
43 | 44 | bilateral = True |
44 | 45 | lookup_name = 'unaccent' |
45 | 46 | function = 'UNACCENT' |
| 47 | |
| 48 | |
| 49 | class JSONIsNull(IsNull): |
| 50 | |
| 51 | def as_sql(self, compiler, connection): |
| 52 | if isinstance(self.lhs, Transform): |
| 53 | sql, params = compiler.compile(self.lhs) |
| 54 | if self.rhs: |
| 55 | return "%s = 'null'" % sql, params |
| 56 | else: |
| 57 | return "%s != 'null'" % sql, params |
| 58 | else: |
| 59 | return super(JSONIsNull, self).as_sql(compiler, connection) |
| 60 | |
| 61 | |
| 62 | class JSONExact(Exact): |
| 63 | |
| 64 | def process_rhs(self, compiler, connection): |
| 65 | result = super(JSONExact, self).process_rhs(compiler, connection) |
| 66 | if result == ('%s', [None]): |
| 67 | return "'null'", [] |
| 68 | return result |
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
|
|
|
981 | 981 | # Interpret '__exact=None' as the sql 'is NULL'; otherwise, reject all |
982 | 982 | # uses of None as a query value. |
983 | 983 | if value is None: |
984 | | if lookups[-1] not in ('exact', 'iexact'): |
985 | | raise ValueError("Cannot use None as a query value") |
986 | | lookups[-1] = 'isnull' |
987 | | value = True |
| 984 | # Some transformed lookup |
| 985 | if lookups[-1] not in self.query_terms: |
| 986 | lookups.append('exact') |
| 987 | else: |
| 988 | if lookups[-1] not in ('exact', 'iexact'): |
| 989 | raise ValueError("Cannot use None as a query value") |
| 990 | lookups[-1] = 'isnull' |
| 991 | value = True |
988 | 992 | elif hasattr(value, 'resolve_expression'): |
989 | 993 | pre_joins = self.alias_refcount.copy() |
990 | 994 | value = value.resolve_expression(self, reuse=can_reuse, allow_joins=allow_joins) |
… |
… |
|
1191 | 1195 | clause.add(condition, AND) |
1192 | 1196 | |
1193 | 1197 | require_outer = lookup_type == 'isnull' and value is True and not current_negated |
1194 | | if current_negated and (lookup_type != 'isnull' or value is False): |
| 1198 | if current_negated and (lookup_type != 'isnull' or value is False) and value is not None: |
1195 | 1199 | require_outer = True |
1196 | 1200 | if (lookup_type != 'isnull' and ( |
1197 | 1201 | self.is_nullable(targets[0]) or |
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
|
|
|
116 | 116 | [self.objs[6]] |
117 | 117 | ) |
118 | 118 | |
| 119 | def test_deep_lookup_isnull(self): |
| 120 | self.assertSequenceEqual( |
| 121 | JSONModel.objects.filter(field__j__isnull=True), |
| 122 | [self.objs[8]] |
| 123 | ) |
| 124 | |
| 125 | def test_deep_lookup_isnull_exclude(self): |
| 126 | obj = JSONModel.objects.create(field={'j': 1}) |
| 127 | self.assertSequenceEqual( |
| 128 | JSONModel.objects.exclude(field__j__isnull=True), |
| 129 | [obj] |
| 130 | ) |
| 131 | |
| 132 | def test_deep_lookup_none_value(self): |
| 133 | self.assertSequenceEqual( |
| 134 | JSONModel.objects.filter(field__j=None), |
| 135 | [self.objs[8]] |
| 136 | ) |
| 137 | |
| 138 | def test_deep_lookup_none_value_exclude(self): |
| 139 | obj = JSONModel.objects.create(field={'j': 1}) |
| 140 | self.assertSequenceEqual( |
| 141 | JSONModel.objects.exclude(field__j=None), |
| 142 | [obj] |
| 143 | ) |
| 144 | |
| 145 | def test_deep_lookup_not_isnull(self): |
| 146 | self.assertSequenceEqual( |
| 147 | JSONModel.objects.filter(field__l__isnull=False), |
| 148 | [self.objs[10]] |
| 149 | ) |
| 150 | |
119 | 151 | def test_exact_complex(self): |
120 | 152 | self.assertSequenceEqual( |
121 | 153 | JSONModel.objects.filter(field__exact={'a': 'b', 'c': 1}), |