DateTimeField tidak ditampilkan di sistem admin

89

Mengapa kolom "tanggal" saya tidak muncul di sistem admin?

Di file admin.py saya, saya punya

from django.contrib import admin
from glasses.players.models import *
admin.site.register(Rating)

dan Model peringkat memiliki bidang yang disebut "tanggal" yang terlihat seperti ini

date = models.DateTimeField(editable=True, auto_now_add=True)

Namun dalam sistem admin, bidang tidak muncul, meskipun editabledisetel ke True.

Apakah ada yang punya ide?

kotor
sumber

Jawaban:

58

Saya percaya alasan terletak pada auto_now_addlapangan.

Dari jawaban ini :

Setiap bidang dengan set atribut auto_now juga akan mewarisi editable = False dan karena itu tidak akan muncul di panel admin.

Juga disebutkan dalam dokumen :

Seperti yang saat ini diterapkan, menyetel auto_now atau auto_now_add ke True akan menyebabkan bidang memiliki editable = False dan blank = True set.

Ini masuk akal, karena tidak ada alasan untuk memiliki bidang yang dapat diedit jika akan ditimpa dengan tanggal waktu saat ini ketika objek disimpan.

Shawn Chin
sumber
31
Padahal tentunya Anda harus bisa mengedit auto_now_addmelalui admin setelah entri pertama kali dibuat?
Christopher Orr
70
Anda juga harus dapat menampilkannya di antarmuka admin, meskipun tidak dapat diedit.
Brad
1
Silakan merujuk ke jawaban oleh @hunger di bawah ini untuk cara menampilkannya sebagai bidang hanya baca di antarmuka admin.
guival
1
Masuk akal untuk memiliki bidang yang dapat diedit jika bidang hanya diinisi pada pembuatan objek (auto_now_add = True).
sergzach
210

Jika Anda benar-benar ingin melihat tanggal di panel admin, Anda dapat menambahkan readonly_fieldsdi admin.py :

class RatingAdmin(admin.ModelAdmin):
    readonly_fields = ('date',)

admin.site.register(Rating,RatingAdmin)

Setiap bidang yang Anda tentukan akan ditambahkan terakhir setelah bidang yang dapat diedit. Untuk mengontrol pesanan Anda dapat menggunakan fieldsopsi.

Informasi tambahan tersedia dari dokumen Django .

Kelaparan
sumber
33
INI adalah jawaban sebenarnya !!
GreenAsJade
4
jika Anda menetapkan a fieldsAnda juga harus meletakkan bidang Anda di dalamnya, jadi Anda akan membutuhkannya di dalam readonly_fieldsdan fieldsjika tidak, bidang tersebut tidak akan muncul.
Bjorn
Saya hanya ingin mencatat bahwa ini juga berlaku jika Anda menggunakan fieldsets, baru saja mengalami masalah ini hari ini.
Kevin Brown
1
Ini akan membuat field hanya muncul ketika kita mengklik dan membuka entri tertentu. Jika Anda ingin bidang tersebut terlihat di listview itu sendiri, maka stackoverflow.com/a/34966908/4440874
Jyotman Singh
1
Catat bahwa saya tidak yakin mengapa tetapi ini tampaknya tidak bekerja untuk DateTimeFields dengan di auto_now_add=Truebawah Django 1.9. Solusi (semacam) adalah menambahkannya ke list_displaytupel sebagai gantinya. Sunting: Ini akan berfungsi jika Anda juga menambahkan bidang Anda ke fieldsseperti yang disebutkan @BjornTipling.
Taylor Edmiston
23

Peretasan Utama:

Jika Anda benar-benar perlu melakukan ini (seperti yang saya lakukan), Anda selalu dapat meretasnya dengan segera menyetel bidang menjadi "dapat diedit" dengan mendefinisikan bidang sebagai berikut:

class Point(models.Model):
  mystamp=models.DateTimeField("When Created",auto_now_add=True)
  mystamp.editable=True

Ini akan membuat bidang dapat diedit, sehingga Anda benar-benar dapat mengubahnya. Tampaknya berfungsi dengan baik, setidaknya dengan mesin pendukung mysql. Saya tidak dapat mengatakan secara pasti jika penyimpanan pendukung lainnya akan membuat data ini tidak dapat diubah dalam database dan dengan demikian menyebabkan masalah saat pengeditan dicoba, jadi gunakan dengan hati-hati .

Brad
sumber
Nah, jangan lakukan ini, gunakan solusi readonly_fields yang dijelaskan oleh Hunger.
GreenAsJade
2
@GreenAsJade: Alasannya bagus.
mhsmith
@mhsmith Rasional untuk menggunakan solusi Hunger daripada ini: karena ini adalah peretasan utama dan dilengkapi dengan "gunakan dengan hati-hati", sedangkan solusi Hunger menggunakan django seperti yang dirancang untuk digunakan. Mengapa Anda mengambil risiko peretasan besar ketika Anda dapat melakukan apa yang Anda butuhkan dengan cara yang sah dan didukung?
GreenAsJade
6
Solusi hack ini tidak terlalu buruk. Satu-satunya kasus penggunaan untuk itu namun saya lihat adalah pengujian - ketika penguji perlu mengubah tanggal.
jacoor
2
hanya peringatan: peretasan ini mengacaukan migrasi untuk saya
damio
16

Bergantung pada kebutuhan spesifik Anda, dan nuansa perbedaan dalam perilaku, Anda dapat melakukan hal berikut:

from django.utils.timezone import now

class MyModel(models.Model):
    date = models.DateTimeField(default=now)

Bidang default dapat digunakan dengan cara ini: https://docs.djangoproject.com/en/dev/ref/models/fields/#default

The default value for the field. This can be a value or a callable object. If callable it will be called every time a new object is created.

Ini tidak dapat diedit ke False

orblivion.dll
sumber
1
Saya akan menggunakan from django.utils.timezone import nowalih-alih datetime.now, tetapi ini terlihat menjanjikan.
amjoconn
Terima kasih, saya mengubahnya.
orblivion
Stackoverflow luar biasa karena, beberapa jawaban membuat Anda sadar bahwa Anda tidak mengajukan pertanyaan yang benar! Terima kasih.
Samuel Dauzon
5

Ini mungkin ada hubungannya dengan auto_now_add menjadi true. Mungkin alih-alih parameter itu untuk menangkap tanggal yang ditambahkan, Anda bisa mengganti metode model save untuk memasukkan datetime ketika id adalah null.

class Rating(models.Model):

    ....
    def save(self, *args, **kwargs)
        if not self.id: 
            self.date = datetime.datetime.now()
Joe J
sumber
Jika Anda melakukannya, maka tidak ada alasan untuk mendefinisikan lapangan sebagai auto_now
fallenangel
Tidak yakin mengapa suara negatifnya; tautan pertama yang disediakan Shawn Chin menunjukkan pendekatan yang serupa.
Joe J
Itu alternatif yang masuk akal, dengan asumsi auto_nowtidak digunakan dan editable=False. +1
Shawn Chin
3

Jika Anda ingin bidang apa pun terlihat dalam daftar semua entri Anda (saat Anda mengeklik model di admin orang) dan bukan saat Anda membuka entri khusus itu -

class RatingAdmin(admin.ModelAdmin):
    list_display = ('name', 'date') 

admin.site.register(Rating, RatingAdmin)

'name' menjadi bidang utama Anda atau bidang lain yang ingin Anda tampilkan di panel admin.

Dengan cara ini Anda dapat menentukan semua kolom yang ingin Anda lihat.

Jyotman Singh
sumber
0

Anda tidak dapat melakukan itu, periksa dokumentasi

auto_now dan auto_now_add adalah semua bidang yang tidak dapat diedit dan Anda tidak dapat menimpanya ...

FallenAngel
sumber