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

WBOY
Freigeben: 2024-02-06 09:48:12
nach vorne
977 Leute haben es durchsucht

如何使用 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)
Nach dem Login kopieren

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",
                    ))
Nach dem Login kopieren

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;
Nach dem Login kopieren

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",
    ))
Nach dem Login kopieren

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"))
Nach dem Login kopieren

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!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!