Foo.objects.get(pk="foo")
<Foo: test>
Dalam database, saya ingin menambahkan objek lain yang merupakan salinan dari objek di atas.
Misalkan meja saya memiliki satu baris. Saya ingin memasukkan objek baris pertama ke baris lain dengan kunci primer yang berbeda. Bagaimana saya bisa melakukan itu?
python
django
django-models
pengguna426795
sumber
sumber
obj.pk
danobj.id
membuat ini bekerja di Django 1.4Dokumentasi Django untuk permintaan basis data mencakup bagian tentang menyalin model instance . Dengan asumsi kunci primer Anda dibuat secara otomatis, Anda mendapatkan objek yang ingin Anda salin, atur kunci utama
None
, dan simpan objek itu lagi:Dalam cuplikan ini, yang pertama
save()
membuat objek asli, dan yang keduasave()
membuat salinan.Jika Anda terus membaca dokumentasi, ada juga contoh tentang bagaimana menangani dua kasus yang lebih kompleks: (1) menyalin objek yang merupakan turunan dari model subkelas, dan (2) juga menyalin objek terkait, termasuk objek dalam banyak -banyak hubungan.
Catatan tentang jawaban miah: Mengatur pk ke
None
disebutkan dalam jawaban miah, meskipun itu tidak disajikan di depan dan tengah. Jadi jawaban saya terutama untuk menekankan metode itu sebagai cara yang direkomendasikan Django untuk melakukannya.Catatan sejarah: Ini tidak dijelaskan dalam dokumen Django sampai versi 1.4. Itu sudah mungkin sejak sebelum 1.4.
Kemungkinan fungsionalitas di masa mendatang: Perubahan dokumen yang disebutkan di atas dibuat dalam tiket ini . Di utas komentar tiket, ada juga beberapa diskusi tentang menambahkan
copy
fungsi bawaan untuk kelas model, tetapi sejauh yang saya tahu mereka memutuskan untuk tidak mengatasi masalah itu. Jadi cara menyalin "manual" ini mungkin harus dilakukan untuk saat ini.sumber
Hati-hati di sini. Ini bisa sangat mahal jika Anda berada dalam satu lingkaran dan Anda mengambil objek satu per satu. Jika Anda tidak ingin panggilan ke database, lakukan saja:
Itu melakukan hal yang sama dengan beberapa jawaban lainnya, tetapi tidak membuat panggilan database untuk mengambil suatu objek. Ini juga berguna jika Anda ingin membuat salinan objek yang belum ada di database.
sumber
Gunakan kode di bawah ini:
sumber
model_to_dict
mengambilexclude
parameter, yang berarti Anda tidak perlu terpisahpop
:model_to_dict(instance, exclude=['id'])
Ada potongan klon di sini , yang dapat Anda tambahkan ke model Anda yang melakukan ini:
sumber
if
sekarang perluif fld.name != old._meta.pk.name
, yaitu,name
properti_meta.pk
instance.Cara melakukan ini ditambahkan ke dokumen resmi Django di Django1.4
https://docs.djangoproject.com/en/1.10/topics/db/queries/#copying-model-inances
Jawaban resmi mirip dengan jawaban miah, tetapi dokumen menunjukkan beberapa kesulitan dengan warisan dan objek terkait, jadi Anda mungkin harus memastikan Anda membaca dokumen.
sumber
stable
alih-alih nomor versi di URL, seperti ini: docs.djangoproject.com/en/stable/topics/db/queries/…Saya telah bertemu dengan beberapa gotcha dengan jawaban yang diterima. Ini solusinya.
Catatan: ini menggunakan solusi yang tidak disetujui secara resmi di dokumen Django, dan mereka mungkin berhenti bekerja di versi mendatang. Saya menguji ini di 1.9.13.
Peningkatan pertama adalah memungkinkan Anda untuk terus menggunakan contoh asli, dengan menggunakan
copy.copy
. Bahkan jika Anda tidak berniat untuk menggunakan kembali instance, itu bisa lebih aman untuk melakukan langkah ini jika instance yang Anda kloning dilewatkan sebagai argumen untuk suatu fungsi. Jika tidak, penelepon secara tak terduga akan memiliki instance yang berbeda ketika fungsi kembali.copy.copy
tampaknya menghasilkan salinan dangkal contoh model Django dengan cara yang diinginkan. Ini adalah salah satu hal yang saya tidak menemukan didokumentasikan, tetapi bekerja dengan pengawetan dan pembongkaran, sehingga mungkin didukung dengan baik.Kedua, jawaban yang disetujui akan meninggalkan hasil prefetch yang melekat pada instance baru. Hasil-hasil itu tidak boleh dikaitkan dengan instance baru, kecuali jika Anda secara eksplisit menyalin ke-banyak hubungan. Jika Anda melintasi hubungan yang diambil sebelumnya, Anda akan mendapatkan hasil yang tidak cocok dengan database. Melanggar kode yang berfungsi saat Anda menambahkan prefetch bisa menjadi kejutan yang tidak menyenangkan.
Menghapus
_prefetched_objects_cache
adalah cara cepat dan kotor untuk menghapus semua prefetch. Akses ke-banyak berikutnya berfungsi seolah-olah tidak pernah ada prefetch. Menggunakan properti tidak berdokumen yang dimulai dengan garis bawah mungkin meminta masalah kompatibilitas, tetapi berfungsi untuk saat ini.sumber
_[model_name]_cache
, yang, setelah dihapus, saya dapat menetapkan ID baru untuk model terkait itu, lalu meneleponsave()
. Mungkin masih ada efek samping yang belum saya tentukan.pengaturan pk ke Tidak ada yang lebih baik, sinse Django dapat dengan benar membuat pk untuk Anda
sumber
Ini adalah cara lain untuk mengkloning instance model:
sumber
Untuk mengkloning model dengan beberapa tingkat warisan, yaitu> = 2, atau ModelC di bawah ini
Silakan merujuk pertanyaan di sini .
sumber
Coba ini
sumber