6

我的模型中有一个 Json 字段 -

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

我的数据库中有值,例如-

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

我正在尝试过滤总计 = 0 的对象,为此我尝试过-

Product.objects.filter(detailed_stock__total = 0) 但它会引发错误 -

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

根据文档,允许使用以下代码。

这是完整的追溯-

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

我在互联网上搜索但无法找到解决方案,请帮助。

4

2 回答 2

10

我认为您使用的是django-jsonfieldload_kwargs={'object_pairs_hook': collections.OrderedDict}不是django.contrib.postgres.fields.JSONField

django-jsonfield适用于不提供本机dict类型且基于简单TextField. 当您使用product.detail_stock内部保存str的访问字段值时,将转换为由字段本身dict使用。json.loads()因此,您只能使用 和 之类的操作icontainscontains查询该字段。

如果您使用 postgres 作为数据库,则可以充分利用django.contrib.postgres.fields.JSONField文档所述的优势。但是您必须JSONfield使用django.contrib.postgres.fields import JSONField.

mysql(包django-mysql)也有一个解决方案。

于 2018-12-31T11:16:00.790 回答
0

如果您正在使用 Django 并使用过:

from json_field import JSONField

那么你就不能从 SQL 查找中受益了。如上所述,JSONField 仅覆盖 TextField。它验证 JSON 格式并转储为字符串。

class JSONField(models.TextField):
    """ Stores and loads valid JSON objects. """

而是使用

from django.db import models
data = models.JSONField(null=True)
于 2020-09-01T11:43:31.143 回答