Heim >Backend-Entwicklung >Python-Tutorial >Wie aktualisiere ich die Werte mehrerer Schlüssel in einem JsonField mithilfe der Methode .update() mithilfe von Djangos ORM?

Wie aktualisiere ich die Werte mehrerer Schlüssel in einem JsonField mithilfe der Methode .update() mithilfe von Djangos ORM?

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBnach vorne
2024-02-06 09:48:121087Durchsuche

如何使用 Django 的 ORM 使用 .update() 方法更新 JsonField 中多个键的值?

Frageninhalt

Ich habe ein Modellfeld, das ich mit Djangos verwenden möchte .update() 方法进行更新。该字段是一个 jsonfield。我通常会在这个领域保存一本字典。例如{"test": "是", "prod": "否"}

Das ist das Modell:

class question(models.model):
    # {"test": "yes", "prod": "no"}
    extra_data = models.jsonfield(default=dict, null=true, blank=true)

Mit dieser Abfrage kann ich die Schlüssel im Wörterbuch aktualisieren (was übrigens hervorragend funktioniert):

Question.filter(id="123").update(meta_data=Func(
                        F("extra_data"),
                        Value(["test"]),
                        Value("no", JSONField()),
                        function="jsonb_set",
                    ))

Die Frage ist nun: Gibt es eine Möglichkeit, mehrere Schlüssel (in meinem Fall zwei) gleichzeitig mit .update() zu aktualisieren, wie in der obigen Abfrage gezeigt?

Ich möchte die .update() 方法而不是 .save()-Methode anstelle von .save() verwenden, um dies zu erreichen, damit ich den Aufruf der Signalfunktion post_save vermeiden kann.


Richtige Antwort


Haftungsausschluss: Es wird hässlich aussehen.

Ich habe das in der Vergangenheit gemacht, allerdings mit reinem SQL, nicht mit Django. Die Idee ist, rekursiv aufzurufen jsonb_set(). Jeder Anruf legt einen Schlüssel fest.

Um in SQL einen Schlüssel {"test":"yes","prod":"no"} festzulegen, gehen Sie wie folgt vor:

update question set meta_data = jsonb_set(jsonb_set(extra_data, '{test}', '"yes"'::jsonb), '{prod}', '"no"'::jsonb)
where id = 123;

Bitte beachten Sie, dass es zwei verschachtelte Aufrufe von jsonb_set gibt, der innerste wird verwendet meta_data und der äußerste erhält das innerste Ergebnis.

Das Django-Äquivalent sieht also so aus (Hinweis, ungetestet):

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",
    ))

Oder Sie könnten eine rekursive Funktion erstellen, die das Durcheinander für Sie zurückgibt und jeweils ein Element festlegt:

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"))

Bitte beachten Sie die '__'-Funktion zum Aktualisieren von Kindern.

Das obige ist der detaillierte Inhalt vonWie aktualisiere ich die Werte mehrerer Schlüssel in einem JsonField mithilfe der Methode .update() mithilfe von Djangos ORM?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen