【问题标题】:Updating JSONField in django rest framework在 django rest 框架中更新 JSONField
【发布时间】:2016-08-09 09:45:32
【问题描述】:

我目前已经熟悉在 django rest-framework 中使用 JSONField,但是我找不到任何直接的方法来更新存储的 json 中的键。过滤 JSONField 的方法有很多,取决于它的内部键,但似乎无法从已存储的 JSONField 中更改、更新或删除键。但似乎 postgres 可以像 this answer 解释的那样对 json 键进行一些修改。

是否有任何功能可以对 JSONFields 进行修改。如果没有任何直接命令可以执行此操作,那么实现 JSONField 修改的最佳方法是什么?

编辑:

例如,如果我有这样的模型:

class Thing(models.Model):
    name = models.CharField()
    properties = JSONField()

properties 中我存储了一个这样的json:

{
"color" : "red",
"size" : "large",
"cost" : 1234
}

然后我想通过使用 django 命令将颜色更改为“绿色”。

【问题讨论】:

  • 您能否举例说明您正在寻找什么样的更新。最简单的方法是读入python,修改成字典,保存。
  • @serg 请查看编辑说明。

标签: django postgresql django-rest-framework


【解决方案1】:
thing = Thing.objects.get(name="...")
thing.properties['color'] = 'green'
thing.save()

【讨论】:

  • 对不起,我现在无法检查您的答案,但我会尽快检查并给您反馈。
  • @serg 我检查了你的答案,我认为thing 中的properties 不像字典或json(它是unicode),所以你需要一些中间操作才能将其更改为字典然后再次保存它。 django 似乎不支持这个,所以我必须像你在这里写的那样做。
  • 应该是字典,你用的是最新的Django,Postgres db 9.4+?属性字段的值是什么,json 作为字符串(unicode)?另外,如果您可以转到 postgres 控制台并检查您的属性字段类型是否为jsonb
  • 对不起,我的回答迟了,你说得对,在当前版本中它是一本字典,尽管在某些情况下它不是一本我觉得奇怪的字典,但在大多数情况下是一本字典。
  • 有没有办法用.update()做到这一点?
【解决方案2】:

您可以在这里找到更好的解决方案 https://django-postgres-extensions.readthedocs.io/en/latest/json.html

【讨论】:

  • 最后那个“__”没有帮助。
【解决方案3】:

对于您的模型:

class Thing(models.Model):
    name = models.CharField()
    properties = JSONField()

如果您需要更新一堆条目,您可以执行以下操作:

Thing.objects.update(
    properties=RawSQL("jsonb_set(properties, '{color}', 'green', true)", [])
)

color: green 将被插入,如果不存在。

欢迎来到PostgreSQL docs,了解更多关于jsonb_set的信息。

【讨论】:

    【解决方案4】:

    下一个语法对我有用,

    • Django==2.2.19
    • Postgres==12.0.6
    from django.db.models.expressions import RawSQL
    Thing.objects.update(properties=RawSQL("""jsonb_set(properties, \'{"name"}\',\'"name value"\', true)""", []))
    

    【讨论】:

      【解决方案5】:

      来自@tarasinf 和@Vladius001 的jsonb_set 方法也适用于Django 的Func expression

      Thing.objects.update(
          properties=Func(
              F("properties"),
              Value(["color"]),
              Value("green", JSONField()),
              function="jsonb_set",
          )
      )
      

      【讨论】:

      • 这是更简洁的更新方式。
      • 请注意,update 方法会立即提交,因此事务回滚将不起作用。至少这是我的经验。
      猜你喜欢
      • 2014-04-21
      • 2018-08-02
      • 1970-01-01
      • 2019-03-05
      • 2020-05-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多