Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django - Unsupported lookup for JSONField or join on the field not permitted

I am having a Json field in my models as -

class Product(models.Model):
    ...
    detailed_stock           = JSONField(load_kwargs={'object_pairs_hook': collections.OrderedDict},default=dict)

I am having values in my database like -

{
  "total":0,
  "5[1]":0
}

I am trying to filter objects with total = 0, for that I tried -

Product.objects.filter(detailed_stock__total = 0) but it throws error -

Unsupported lookup 'total' for JSONField or join on the field not permitted.

as per the documentation the following code is permitted.

this is full traceback-

Traceback (most recent call last):
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\core\handlers\exception.py", line 35, in inner
    response = get_response(request)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\core\handlers\base.py", line 128, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\views\generic\base.py", line 69, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\braces\views\_access.py", line 102, in dispatch
    request, *args, **kwargs)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\views\generic\base.py", line 89, in dispatch
    return handler(request, *args, **kwargs)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\views\generic\list.py", line 142, in get
    self.object_list = self.get_queryset()
  File "c:\Users\lenovo\Desktop\My_Django_Stuff\bekaim\accounts\views.py", line 142, in get_queryset
    queryset = Product.objects.filter(detailed_stock__total = 0)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\query.py", line 836, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\query.py", line 854, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\sql\query.py", line 1253, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\sql\query.py", line 1271, in _add_q
    current_negated, allow_joins, split_subq)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\sql\query.py", line 1277, in _add_q
    split_subq=split_subq,
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\sql\query.py", line 1215, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\sql\query.py", line 1069, in build_lookup
    lhs = self.try_transform(lhs, name)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\sql\query.py", line 1115, in try_transform
    (name, lhs.output_field.__class__.__name__))
django.core.exceptions.FieldError: Unsupported lookup 'total' for JSONField or join on the field not permitted.
[31/Dec/2018 16:13:37] "GET /accounts/product-list/?clean=outofstock HTTP/1.1" 500 150927

I searched on internet but unable to find the solution, please help.

like image 482
Pankaj Sharma Avatar asked Dec 31 '18 11:12

Pankaj Sharma


1 Answers

I think you are using django-jsonfield as indicated by load_kwargs={'object_pairs_hook': collections.OrderedDict} instead of django.contrib.postgres.fields.JSONField.

django-jsonfield is for databases which don't offer a native dict type and is based on a simple TextField. When you access the field value using product.detail_stock the internally saved str is converted to dict using json.loads() by the field itself. Hence you can only use operations like icontains and contains for querying that field.

If you are using postgres as a database, you are able to take full advantage of django.contrib.postgres.fields.JSONField as the documentation states. But you have to import the correct JSONfield by using django.contrib.postgres.fields import JSONField.

There is a solution for mysql (package django-mysql) too.

like image 133
escaped Avatar answered Sep 19 '22 06:09

escaped