Maison >développement back-end >Tutoriel Python >Comment mettre à jour les valeurs de plusieurs clés dans un JsonField à l'aide de la méthode .update() à l'aide de l'ORM de Django ?
J'ai un champ de modèle que j'essaie d'utiliser avec celui de Django .update()
方法进行更新。该字段是一个 jsonfield。我通常会在这个领域保存一本字典。例如{"test": "是", "prod": "否"}
Voici le modèle :
class question(models.model): # {"test": "yes", "prod": "no"} extra_data = models.jsonfield(default=dict, null=true, blank=true)
Je peux mettre à jour les clés dans le dictionnaire en utilisant cette requête (qui fonctionne très bien d'ailleurs) :
Question.filter(id="123").update(meta_data=Func( F("extra_data"), Value(["test"]), Value("no", JSONField()), function="jsonb_set", ))
Maintenant, la question est la suivante : existe-t-il un moyen de mettre à jour plusieurs clés (dans mon cas, deux) à la fois en utilisant .update()
comme indiqué dans la requête ci-dessus ?
Je souhaite utiliser la méthode .update()
方法而不是 .save()
au lieu de .save()
pour y parvenir afin d'éviter d'appeler la fonction de signal post_save.
Avertissement : cela aura l'air moche.
Je l'ai fait dans le passé, bien qu'en utilisant du SQL pur, pas Django. L'idée est d'appeler de manière récursive jsonb_set()
. Chaque appel définit une clé.
Donc, en SQL, pour définir une clé {"test":"yes","prod":"no"}
vous faites :
update question set meta_data = jsonb_set(jsonb_set(extra_data, '{test}', '"yes"'::jsonb), '{prod}', '"no"'::jsonb) where id = 123;
Veuillez noter qu'il existe deux appels imbriqués à jsonb_set, celui le plus interne est utilisé meta_data
et celui le plus externe reçoit le résultat le plus interne.
Donc l'équivalent de Django ressemble à ceci (note, non testé) :
question.filter(id="123").update( meta_data=func( func( f("extra_data"), value(["test"]), value("yes", jsonfield()), function="jsonb_set", ), value(["prod"]), value("no", jsonfield()), function="jsonb_set", ))
Ou vous pouvez créer une fonction récursive qui renvoie le désordre pour vous, en définissant un élément à la fois :
def recursive_jsonb_set(original, **kwargs): if kwargs: key, value = kwargs.popitem() return Func( recursive_jsonb_set(original, **kwargs), Value(key.split('__')), Value(value, JSONField()), function="jsonb_set") else: return original Question.filter(id="123").update( meta_data=recursive_jsonb_set(F("extra_data"), test="yes", prod="no", other__status="done"))
Veuillez noter la fonction '__'
pour mettre à jour les enfants.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!