【问题标题】:Why does Django return postgres JSONField value as string?为什么 Django 将 postgres JSONField 值作为字符串返回?
【发布时间】:2017-08-03 22:18:57
【问题描述】:

环境:

  • Django 1.10.6
  • psycopg2 2.7.1
  • 通过 Homebrew 在 macOS Sierra 上安装 PostgreSQL 9.6.2
  • 通过 Homebrew 安装的 Python 3.6.0

示例模型:

from django.db import models
from django.contrib.postgres.fields import JSONField


class Foo(models.Model):
    data = JSONField()

当我尝试创建一个对象时,一切都按预期工作:

from myapp.models import Foo
x = Foo()
x.data = {'key1': 'value1'}
x.save()

查询按预期工作:

Foo.objects.filter(data__key1='value1').count()
# 1

但是,当我尝试从对象中检索该数据时,.data 属性的值是一个字符串:

from myapp.models import Foo
x = Foo.objects.get(id=1)
x.data
# '{"key1": "value1"}'
type(x.data)
# str

我希望在这里得到一个字典。尝试保存对象时,问题会递归地变得更糟

x.save()
x = Foo.objects.get(id=1)
x.data
# '"{\\"key1\\": \\"value1\\"}"'
x.save()
x = Foo.objects.get(id=1)
x.data
# '"\\"{\\\\\\"key1\\\\\\": \\\\\\"value1\\\\\\"}\\""'

【问题讨论】:

  • 这不应该发生。你能展示你的完整模型吗?您是否有任何验证器、自定义保存方法或附加到保存事件的任何信号?
  • 我开始从项目中安装的其他应用程序向后工作,发现罪魁祸首是这个应用程序github.com/jjkester/django-auditlog。当我从 MIDDLEWARE 和 INSTALLED_APPS 中删除它时,一切都按预期工作。进一步看,该项目需要 django-jsonfield 并且两者之间一定存在一些不兼容
  • 事实上它已经是该项目中的一个未解决问题github.com/jjkester/django-auditlog/issues/71

标签: python json django postgresql


【解决方案1】:

原来你不能在同一个项目中使用 django-jsonfield 和 Django 的原生 JSONField,否则你会遇到问题中描述的奇怪行为

https://bitbucket.org/schinckel/django-jsonfield/issues/57/cannot-use-in-the-same-project-as-djangos

【讨论】:

    【解决方案2】:

    对我来说,问题是数据库是从备份创建的,列类型设置为text,而它本应为jsonjsonb

    清除所有无效的 json,然后使用以下内容更改列类型:

    ALTER TABLE t ALTER COLUMN j TYPE jsonb USING j::text::jsonb;
    

    (感谢https://stackoverflow.com/a/28076909/2362877

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-14
      • 2011-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-23
      • 1970-01-01
      • 2011-11-04
      相关资源
      最近更新 更多