Saya punya model seperti ini:
class FooBar(models.Model):
createtime = models.DateTimeField(auto_now_add=True)
lastupdatetime = models.DateTimeField(auto_now=True)
Saya ingin menimpa dua bidang tanggal untuk beberapa contoh model (digunakan saat memigrasi data). Solusi saat ini terlihat seperti ini:
for field in new_entry._meta.local_fields:
if field.name == "lastupdatetime":
field.auto_now = False
elif field.name == "createtime":
field.auto_now_add = False
new_entry.createtime = date
new_entry.lastupdatetime = date
new_entry.save()
for field in new_entry._meta.local_fields:
if field.name == "lastupdatetime":
field.auto_now = True
elif field.name == "createtime":
field.auto_now_add = True
Apakah ada solusi yang lebih baik?
auto_now(_add)
Jawaban:
Saya baru-baru ini menghadapi situasi ini saat menguji aplikasi saya. Saya perlu "memaksa" stempel waktu yang kedaluwarsa. Dalam kasus saya, saya melakukan trik dengan menggunakan pembaruan queryset. Seperti ini:
sumber
update()
perilaku ini persis seperti yang kita butuhkan.Anda tidak dapat benar-benar menonaktifkan auto_now / auto_now_add dengan cara lain daripada yang sudah Anda lakukan. Jika Anda membutuhkan fleksibilitas untuk mengubah nilai-nilai itu,
auto_now
/auto_now_add
bukanlah pilihan terbaik. Seringkali lebih fleksibel untuk menggunakandefault
dan / atau menggantisave()
metode untuk melakukan manipulasi tepat sebelum objek disimpan.Menggunakan
default
dansave()
metode yang diganti , salah satu cara untuk menyelesaikan masalah Anda adalah dengan mendefinisikan model Anda seperti ini:Dalam kode Anda, di mana Anda ingin melewati perubahan waktu terakhir otomatis, cukup gunakan
Jika objek Anda disimpan di antarmuka admin atau tempat lain, save () akan dipanggil tanpa argumen skip_lastupdatetime, dan itu akan berperilaku seperti sebelumnya dengan
auto_now
.sumber
auto_now_add
gunakandefault
sebagai gantinya.datetime.datetime.now
mengembalikan tanggal waktu naif. Untuk menggunakan tanggal waktu sadar zona, gunakanfrom django.utils import timezone
danmodels.DateTimeField(default=timezone.now)
lihat docs.djangoproject.com/en/1.9/topics/i18n/timezones/…createtime
bidang, Anda tidak perlu menimpasave()
. Cukup digantiauto_now_add=True
dengan yang setaradefault=timezone.now, editable=False, blank=True
(menurut dokumen ). Dua opsi terakhir memastikan perilaku serupa di admin.Saya menggunakan saran yang dibuat oleh penanya, dan membuat beberapa fungsi. Berikut kasus penggunaannya:
Berikut implementasinya:
Fungsi serupa dapat dibuat untuk mengaktifkannya kembali.
sumber
Clazz._meta.get_field_by_name(field_name)[0]
.Anda juga dapat menggunakan
update_fields
parametersave()
dan meneruskanauto_now
bidang Anda . Berikut contohnya:Berikut penjelasan dari dokumentasi Django: https://docs.djangoproject.com/en/stable/ref/models/instances/#specifying-which-fields-to-save
sumber
auto_now
danauto_now_add
).Saya menggunakan cara manajer konteks untuk dapat digunakan kembali.
Gunakan seperti ini:
Ledakan.
sumber
Bagi mereka yang melihat ini ketika mereka menulis tes, ada pustaka python yang disebut freezegun yang memungkinkan Anda untuk memalsukan waktu - jadi ketika
auto_now_add
kode berjalan, ia mendapatkan waktu yang Anda inginkan. Begitu:Ini juga dapat digunakan sebagai dekorator - lihat tautan di atas untuk dokumen dasar.
sumber
Anda dapat mengganti
auto_now_add
tanpa kode khusus.Saya menemukan pertanyaan ini ketika saya mencoba membuat objek dengan tanggal tertentu:
dimana
publication_date = models.DateField(auto_now_add=True)
.Jadi inilah yang telah saya lakukan:
Ini telah berhasil diganti
auto_now_add
.Sebagai solusi jangka panjang,
save
metode utama adalah cara yang tepat: https://code.djangoproject.com/ticket/16583sumber
Saya perlu menonaktifkan auto_now untuk bidang DateTime selama migrasi dan dapat melakukan ini.
sumber
Saya terlambat ke pesta, tetapi mirip dengan beberapa jawaban lainnya, ini adalah solusi yang saya gunakan selama migrasi database. Perbedaan dari jawaban lain adalah bahwa ini menonaktifkan semua kolom auto_now untuk model dengan asumsi bahwa sebenarnya tidak ada alasan untuk memiliki lebih dari satu kolom seperti itu.
Kemudian untuk menggunakannya, Anda cukup melakukan:
Dan itu akan melalui dan nuke semua Anda
auto_now
danauto_now_add
bidang untuk semua kelas model yang Anda lewati.sumber
Versi pengelola konteks yang lebih bersih dari https://stackoverflow.com/a/35943149/1731460
Anda dapat menggunakannya bahkan dengan Pabrik (pabrik-anak)
sumber
salinan Django - Models.DateTimeField - Mengubah nilai auto_now_add dinamis
Nah, saya habiskan sore ini untuk mencari tahu dan masalah pertama adalah bagaimana mengambil model objek dan di mana dalam kode. Saya dalam restframework di serializer.py, misalnya di
__init__
serializer itu belum bisa memiliki Model. Sekarang di to_internal_value Anda bisa mendapatkan kelas model, setelah mendapatkan Bidang dan setelah memodifikasi properti bidang seperti dalam contoh ini:sumber
Saya membutuhkan solusi yang akan berfungsi
update_or_create
, saya datang ke solusi ini berdasarkan kode @andreaspelme.Satu-satunya perubahan adalah Anda dapat menyetel skipping dengan menyetel bidang yang diubah menjadi
skip
tidak hanya dengan benar-benar meneruskan metode kwargskip_modified_update
to save ().Hanya
yourmodelobject.modified='skip'
dan pembaruan akan dilewati!sumber