I see two problems here.
The Django filter options are there to filter for Django objects, not objects within a field. You could definitely filter for an object that contains a task "test" but you cannot filter for the specific task within the JSONField in the object (you need to first retrieve the content of the django object and then query in an additional step)
As far as I understand the django documentation on JSONField, the contains
operator only checks for keys in a dictionary or elements in a list. Appending it to a lookup query in hope that it compares a value like I understand your examples will thus not work. However, it is possible to query a dictionary with contains
. In your case, this should work for querying the django object:
myModel.objects.filter(tasks__contains={"task": "test"})
If you are only interested in the one dictionary and not the others, you will need to expand this query by afterwards extracting the correct object:
matching_objects = myModel.objects.filter(tasks__contains={"task": "test"})
for matching_object in matching_objects:
for matching_task in [task for task in matching_object.tasks if "task" in task and task["task"] == "test" ]:
print "found task", matching_task
See also this related stackoverflow answer for lookups in JSONFields with contains
.
Update: Django versions 3.1+
Later Django versions (3.1+) have a generally available JSONField.
This field is not purely bound to Postgres anymore. Instead, it works (according to the Django documentation for version 4.0) with
MariaDB 10.2.7+, MySQL 5.7.8+, Oracle, PostgreSQL, and SQLite (with the JSON1 extension enabled)
The contains
operator will check for matching key/value pairs on the root level of the dictionary here. Still, it would not pick up test 123
as the question asked for.