JSONModel.objects.create(field={‘key’: None})
JSONModel.objects.create(field={‘key’: 1})
}}}
Now lets get all objects where key is None:
{{{
>>> JSONModel.objects.filter(field__key__isnull=True)
}}}
Will fail with:
{{{
ProgrammingError: operator does not exist: jsonb -> boolean
LINE 1: ...onmodel" WHERE "postgres_tests_jsonmodel"."field" -> ‘key' IS
...
^
HINT: No operator matches the given name and argument type(s). You might
need to add explicit type casts.
}}}
Generated SQL:
{{{
SELECT "postgres_tests_jsonmodel"."id", "postgres_tests_jsonmodel"."field"
FROM "postgres_tests_jsonmodel" WHERE "postgres_tests_jsonmodel"."field"
-> ‘key' IS NULL;
}}}
Which is obviously incorrect.
Next try:
{{{
>>> JSONModel.objects.filter(field__key=None)
}}}
Will fail with:
{{{
ValueError: Cannot use None as a query value at
django.db.models.sql.query, line 985, in prepare_lookup_value
}}}
Will also fail:
{{{
JSONModel.objects.filter(field__key='null’)
}}}
Correct query should be:
{{{
SELECT "postgres_tests_jsonmodel"."id", "postgres_tests_jsonmodel"."field"
FROM "postgres_tests_jsonmodel" WHERE "postgres_tests_jsonmodel"."field"
-> ‘key' = 'null';
}}}
In my patch JSONField uses slightly modified lookups. Any thoughts? Is it
a good approach to solve this problem?
--
Ticket URL: <https://code.djangoproject.com/ticket/25718>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* Attachment "json_null.patch" added.
* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0
Comment:
Changes is here:
https://github.com/django/django/compare/master...Stranger6667:fix-json-
isnull-lookups?expand=1
--
Ticket URL: <https://code.djangoproject.com/ticket/25718#comment:1>
* cc: charettes (added)
* stage: Unreviewed => Accepted
Comment:
Hi Stranger6667, thanks for the report and patch!
At a first glance you proposed changes make sense.
Please create a PR out of this branch and link back to it here as it will
give it more visibility and allows running CI against the iterations of
your patch.
Once this is done, detailing why this requires changing code outside the
`django.contrib.postgres` package would also help future reviewers.
Accepting based on the detailed report and the fact that we need an API to
query `null` values.
--
Ticket URL: <https://code.djangoproject.com/ticket/25718#comment:2>
* owner: => Stranger6667
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/25718#comment:3>
Comment (by Stranger6667):
PR: https://github.com/django/django/pull/5617
--
Ticket URL: <https://code.djangoproject.com/ticket/25718#comment:4>
* version: 1.8 => master
--
Ticket URL: <https://code.djangoproject.com/ticket/25718#comment:5>
* needs_better_patch: 0 => 1
Comment:
Marking "Patch needs improvement" given Marc's feedback on the pull
request.
--
Ticket URL: <https://code.djangoproject.com/ticket/25718#comment:6>
* needs_better_patch: 1 => 0
Comment:
[https://github.com/django/django/pull/8239 PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/25718#comment:7>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/25718#comment:8>
* needs_better_patch: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/25718#comment:9>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/25718#comment:10>
* needs_better_patch: 1 => 0
* stage: Accepted => Ready for checkin
Comment:
For me, I think this is now good to go. (Not 100% sure about
`versionchanged` vs `versionadded` here...)
--
Ticket URL: <https://code.djangoproject.com/ticket/25718#comment:11>
* needs_better_patch: 0 => 1
* stage: Ready for checkin => Accepted
--
Ticket URL: <https://code.djangoproject.com/ticket/25718#comment:12>
* needs_better_patch: 1 => 0
* stage: Accepted => Ready for checkin
Comment:
Release notes and docs have been updated to reflect changes. (Including BC
change if you were using `=None` to query for `__isnull`.) Should be good
to go.
--
Ticket URL: <https://code.djangoproject.com/ticket/25718#comment:13>
* needs_better_patch: 0 => 1
* stage: Ready for checkin => Accepted
Comment:
Looking good, but I think `HStoreField` should have the same behavior.
--
Ticket URL: <https://code.djangoproject.com/ticket/25718#comment:14>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"c979c0a2b8abca325a549961fd7a17bdc36bcb1f" c979c0a]:
{{{
#!CommitTicketReference repository=""
revision="c979c0a2b8abca325a549961fd7a17bdc36bcb1f"
Fixed #25718 -- Made a JSONField lookup value of None match keys that have
a null value.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/25718#comment:15>