0

JSONField我像这样即时注释。由于这不是模型的领域,我认为模型不相关。这个例子应该对任何查询集都有效。

>>> from django.db.models import F, Func, JSONField, Value

>>> queryset = queryset.annotate(
        json=Func(Value("foo"), Value("bar"), function="jsonb_build_object", output_field=JSONField())
    )

>>> queryset.first().json
{'foo': 'bar'}

现在,当我想通过调用来检索带注释的 JSONField 的值时values,我收到一个错误:

>>> queryset.values("json__foo")
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 841, in values
    clone = self._values(*fields, **expressions)
  File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 836, in _values
    clone.query.set_values(fields)
  File "/usr/local/lib/python3.9/site-packages/django/db/models/sql/query.py", line 2174, in set_values
    self.add_fields(field_names, True)
  File "/usr/local/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1863, in add_fields
    join_info = self.setup_joins(name.split(LOOKUP_SEP), opts, alias, allow_many=allow_m2m)
  File "/usr/local/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1565, in setup_joins
    path, final_field, targets, rest = self.names_to_path(
  File "/usr/local/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1481, in names_to_path
    raise FieldError("Cannot resolve keyword '%s' into field. "
django.core.exceptions.FieldError: Cannot resolve keyword 'json' into field. Choices are: <other fields> 

通过从先前注释的字段中检索字段来注释字段JSONField也不起作用:

>>> queryset.annotate(foo=F("json__foo"))
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 1116, in annotate
    clone.query.add_annotation(annotation, alias, is_summary=False)
  File "/usr/local/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1018, in add_annotation
    annotation = annotation.resolve_expression(self, allow_joins=True, reuse=None,
  File "/usr/local/lib/python3.9/site-packages/django/db/models/expressions.py", line 539, in resolve_expression
    return query.resolve_ref(self.name, allow_joins, reuse, summarize)
  File "/usr/local/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1692, in resolve_ref
    join_info.transform_function(targets[0], final_alias)
  File "/usr/local/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1583, in transform
    wrapped = previous(field, alias)
  File "/usr/local/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1558, in final_transformer
    return field.get_col(alias)
  File "/usr/local/lib/python3.9/site-packages/django/db/models/fields/__init__.py", line 398, in get_col
    if alias != self.model._meta.db_table or output_field != self:
AttributeError: 'JSONField' object has no attribute 'model'

根据Querying JSONField() - Key, index and path transforms上的 Django 文档,我希望这两个命令都能正常工作。

这可以被认为是一个错误还是我做错了?

4

1 回答 1

1

因此,如果您需要 json 字段中特定键的值,并且这仅在您使用postgresql时有效,您可以这样做:-

from django.db.models import F, Func, JSONField, Value
from django.contrib.postgres.fields.jsonb import KeyTransform
queryset = queryset.annotate(
    json=Func(Value("foo"), Value("bar"), function="jsonb_build_object", output_field=JSONField()), 
    foo_value=KeyTransform('foo', 'json')
)
queryset.values('foo_value')
于 2021-03-31T13:24:42.253 回答