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

WBOY
Lepaskan: 2024-02-06 09:48:12
ke hadapan
977 orang telah melayarinya

如何使用 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)
Salin selepas log masuk

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",
                    ))
Salin selepas log masuk

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;
Salin selepas log masuk

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",
    ))
Salin selepas log masuk

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"))
Salin selepas log masuk

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!

sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!