Saya telah mencari jawaban untuk ini di situs Selatan, Google, dan SO, tetapi tidak dapat menemukan cara sederhana untuk melakukan ini.
Saya ingin mengganti nama model Django menggunakan Selatan. Katakanlah Anda memiliki yang berikut ini:
class Foo(models.Model):
name = models.CharField()
class FooTwo(models.Model):
name = models.CharField()
foo = models.ForeignKey(Foo)
dan Anda ingin mengonversi Foo ke Bar, yaitu
class Bar(models.Model):
name = models.CharField()
class FooTwo(models.Model):
name = models.CharField()
foo = models.ForeignKey(Bar)
Sederhananya, saya hanya mencoba mengubah nama dari Foo
menjadi Bar
, tetapi abaikan foo
anggota FooTwo
untuk saat ini.
Apa cara termudah untuk melakukan ini menggunakan Selatan?
- Saya mungkin bisa melakukan migrasi data, tetapi itu tampaknya cukup terlibat.
- Tulis migrasi khusus, misalnya
db.rename_table('city_citystate', 'geo_citystate')
, tetapi saya tidak yakin bagaimana cara memperbaiki kunci asing dalam kasus ini. - Cara mudah yang Anda tahu?
python
django
django-models
rename
django-south
vaughnkoch
sumber
sumber
Jawaban:
Untuk menjawab pertanyaan pertama Anda, penggantian nama model / tabel sederhana cukup mudah. Jalankan perintah:
(Pembaruan 2: cobalah
--auto
alih-alih--empty
menghindari peringatan di bawah ini. Terima kasih kepada @KFB untuk tipnya.)Jika Anda menggunakan versi lama dari selatan, Anda harus
startmigration
bukannyaschemamigration
.Kemudian edit file migrasi secara manual agar terlihat seperti ini:
Anda dapat melakukannya lebih mudah dengan menggunakan
db_table
opsi Meta di kelas model Anda. Tetapi setiap kali Anda melakukannya, Anda menambah bobot warisan basis kode Anda - memiliki nama kelas yang berbeda dari nama tabel membuat kode Anda lebih sulit untuk dipahami dan dipelihara. Saya sepenuhnya mendukung melakukan refactor sederhana seperti ini demi kejelasan.(pembaruan) Saya baru saja mencoba ini dalam produksi, dan mendapat peringatan aneh ketika saya pergi untuk menerapkan migrasi. Itu berkata:
Saya menjawab "tidak" dan semuanya tampak baik-baik saja.
sumber
Lakukan perubahan
models.py
lalu jalankanSaat Anda memeriksa file migrasi, Anda akan melihat bahwa itu menghapus tabel dan membuat yang baru
Ini tidak seperti yang Anda inginkan. Alih-alih, edit migrasi sehingga terlihat seperti:
Dengan tidak adanya
update
pernyataan,db.send_create_signal
panggilan akan membuat yang baruContentType
dengan nama model yang baru. Tapi itu lebih baik untuk hanyaupdate
yangContentType
sudah Anda miliki dalam kasus ada objek database menunjuk ke itu (misalnya, melaluiGenericForeignKey
).Juga, jika Anda telah mengganti nama beberapa kolom yang merupakan kunci asing untuk model yang diubah namanya, jangan lupa untuk melakukannya
sumber
contenttypes.ContentType
model ke model beku dengan menggunakan--frozen
flag untuk./manage.py datamigration
. Sebagai contoh:./manage.py datamigration --frozen contenttypes myapp update_contenttypes
. Kemudian edit myapp_migrations / NNNN_update_contenttypes.py dengan kode pembaruan jenis konten seperti yang ditentukan di atas.Selatan tidak bisa melakukannya sendiri - bagaimana ia tahu itu
Bar
mewakili apa yangFoo
dulu? Ini adalah jenis hal yang ingin saya tuliskan migrasi khusus. Anda dapat mengubahForeignKey
kode Anda seperti yang Anda lakukan di atas, dan itu hanya kasus mengubah nama bidang dan tabel yang sesuai, yang dapat Anda lakukan dengan cara apa pun yang Anda inginkan.Akhirnya, apakah Anda benar-benar perlu melakukan ini? Saya belum perlu mengubah nama model - nama model hanyalah detail implementasi - terutama mengingat ketersediaan
verbose_name
opsi Meta.sumber
db_table
opsi Meta untuk menjaga nama tabel database tetap sama.db_table
digunakan untuk mendapatkan nama kunci asing?Saya mengikuti solusi Leopd di atas. Tapi, itu tidak mengubah nama model. Saya mengubahnya secara manual dalam kode (juga dalam model terkait di mana ini disebut sebagai FK). Dan melakukan migrasi selatan lain, tetapi dengan opsi --fake. Ini membuat nama model dan nama tabel menjadi sama.
Baru sadar, seseorang dapat mulai dengan mengubah nama model, kemudian mengedit file migrasi sebelum menerapkannya. Jauh lebih bersih.
sumber