Rumah >pembangunan bahagian belakang >Tutorial Python >Bagaimana untuk mengemas kini nilai berbilang kunci dalam JsonField menggunakan kaedah .update() menggunakan ORM Django?

Bagaimana untuk mengemas kini nilai berbilang kunci dalam JsonField menggunakan kaedah .update() menggunakan ORM Django?

WBOY
WBOYke hadapan
2024-02-06 09:48:121044semak imbas

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

Kandungan soalan

Saya mempunyai medan model yang saya cuba gunakan dengan Django's .update() 方法进行更新。该字段是一个 jsonfield。我通常会在这个领域保存一本字典。例如{"test": "是", "prod": "否"}

Ini modelnya:

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

Saya boleh mengemas kini kunci dalam kamus menggunakan pertanyaan ini (yang berfungsi dengan baik):

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

Sekarang persoalannya, adakah cara yang boleh saya gunakan .update() untuk mengemas kini berbilang kunci (dalam kes saya sendiri dua) serentak seperti yang ditunjukkan dalam pertanyaan di atas?

Saya mahu menggunakan kaedah .update() 方法而不是 .save() dan bukannya .save() untuk mencapai ini supaya saya boleh mengelak daripada memanggil fungsi isyarat post_save.


Jawapan Betul


Penafian: Ia akan kelihatan hodoh.

Saya pernah melakukan ini pada masa lalu, walaupun menggunakan sql tulen, bukan django. Ideanya adalah untuk memanggil secara rekursif jsonb_set(). Setiap panggilan menetapkan kunci.

Jadi, dalam sql, untuk menetapkan kunci {"test":"yes","prod":"no"} anda lakukan:

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

Sila ambil perhatian bahawa terdapat dua panggilan bersarang ke jsonb_set, yang paling dalam digunakan meta_data, dan yang paling luar menerima hasil yang paling dalam.

Jadi persamaan django kelihatan seperti ini (nota, belum diuji):

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

Atau anda boleh mencipta fungsi rekursif yang mengembalikan kekacauan untuk anda, menetapkan satu item pada satu masa:

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

Sila ambil perhatian fungsi '__' untuk mengemas kini kanak-kanak.

Atas ialah kandungan terperinci Bagaimana untuk mengemas kini nilai berbilang kunci dalam JsonField menggunakan kaedah .update() menggunakan ORM Django?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam