Ticket #25718: json_null.patch

File json_null.patch, 4.9 KB (added by Dmitry Dygalo, 8 years ago)
  • django/contrib/postgres/fields/jsonb.py

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    6464JSONField.register_lookup(lookups.HasKey)
    6565JSONField.register_lookup(lookups.HasKeys)
    6666JSONField.register_lookup(lookups.HasAnyKeys)
     67JSONField.register_lookup(lookups.JSONIsNull)
     68JSONField.register_lookup(lookups.JSONExact)
    6769
    6870
    6971class KeyTransform(Transform):
  • django/contrib/postgres/lookups.py

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    11from django.db.models import Lookup, Transform
     2from django.db.models.lookups import IsNull, Exact
    23
    34
    45class PostgresSimpleLookup(Lookup):
     
    4344    bilateral = True
    4445    lookup_name = 'unaccent'
    4546    function = 'UNACCENT'
     47
     48
     49class 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
     62class 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
  • django/db/models/sql/query.py

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    981981        # Interpret '__exact=None' as the sql 'is NULL'; otherwise, reject all
    982982        # uses of None as a query value.
    983983        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
    988992        elif hasattr(value, 'resolve_expression'):
    989993            pre_joins = self.alias_refcount.copy()
    990994            value = value.resolve_expression(self, reuse=can_reuse, allow_joins=allow_joins)
     
    11911195        clause.add(condition, AND)
    11921196
    11931197        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:
    11951199            require_outer = True
    11961200            if (lookup_type != 'isnull' and (
    11971201                    self.is_nullable(targets[0]) or
  • tests/postgres_tests/test_json.py

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    116116            [self.objs[6]]
    117117        )
    118118
     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
    119151    def test_exact_complex(self):
    120152        self.assertSequenceEqual(
    121153            JSONModel.objects.filter(field__exact={'a': 'b', 'c': 1}),
Back to Top