DateTimeField не отображается в системе администратора


88

Почему мое поле "Дата" не отображается в системе администратора?

В моем файле admin.py у меня есть

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

а в рейтинговой модели есть поле под названием «дата», которое выглядит так

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

Однако в системе администратора это поле не отображается, даже если для editableнего установлено значение True.

Есть у кого-нибудь идеи?

Ответы:


56

Я считаю, что разум лежит в auto_now_addполе.

Из этого ответа :

Любое поле с установленным атрибутом auto_now также унаследует editable = False и, следовательно, не будет отображаться в панели администратора.

Также упоминается в документах :

В текущей реализации установка auto_now или auto_now_add на True приведет к тому, что для поля будут установлены editable = False и blank = True.

Это имеет смысл, поскольку нет причин для редактирования поля, если оно будет перезаписано текущим значением даты и времени при сохранении объекта.


31
Хотя, конечно, у вас должна быть возможность редактировать auto_now_addчерез администратора после того, как запись была впервые создана?
— Christopher Orr

68
Вы также должны иметь возможность просто отображать его в интерфейсе администратора, даже если он не редактировался.
— Брэд

1
Пожалуйста, обратитесь к ответу @hunger ниже, чтобы узнать, как отобразить его как поле только для чтения в интерфейсе администратора.
— guival 06

1
Имеет смысл иметь редактируемое поле, если поле вводится только при создании объекта (auto_now_add = True).
— sergzach

206

Если вы действительно хотите видеть дату в панели администратора, вы можете добавить readonly_fieldsв admin.py :

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

admin.site.register(Rating,RatingAdmin)

Любое указанное вами поле будет добавлено последним после редактируемых полей. Для управления порядком вы можете использовать fieldsопции.

Дополнительную информацию можно найти в документации Django .


33
ЭТО настоящий ответ !!
— GreenAsJade

4
если вы укажете a, fieldsвы также должны поместить в него свое поле, чтобы оно понадобилось вам как внутри, так readonly_fieldsи fieldsиначе поле не будет отображаться.
— Bjorn

Я просто хотел отметить, что это также применимо, если вы используете fieldsets, только что столкнулся с этой проблемой сегодня.
— Кевин Браун,

1
Это заставит поле появляться только тогда, когда мы щелкнем и откроем конкретную запись. Если вы хотите, чтобы поле было видно в самом
— списке,

1
Обратите внимание, что я не уверен, почему, но это не работает для DateTimeFields auto_now_add=Trueв Django 1.9. Временным решением (своего рода) является добавление их в list_displayкортеж. Изменить: он будет работать, если вы также добавите свое поле, fieldsкак указано в @BjornTipling.
— Тейлор Эдмистон

23

Основной взлом:

Если вам действительно нужно это сделать (как и мне), вы всегда можете обойти это, сразу же установив для поля значение «редактируемое», определив поле следующим образом:

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

Это сделает поле доступным для редактирования, так что вы действительно сможете его изменить. Кажется, он работает нормально, по крайней мере, с механизмом поддержки mysql. Я не могу сказать для certian, если другие резервные хранилища сделают эти данные неизменяемыми в базе данных и, таким образом, вызовут проблему при попытке редактирования, поэтому используйте с осторожностью .


Нет, не делайте этого, используйте решение readonly_fields, описанное Hunger.
— GreenAsJade

2
@GreenAsJade: Было бы неплохо обосновать это.
— mhsmith

@mhsmith Обоснование использования решения Hunger вместо этого: потому что это серьезный взлом и идет с «осторожностью», тогда как решение Hunger использует django так, как оно предназначено для использования. Зачем вам рисковать серьезным взломом, если вы можете делать то, что вам нужно, законным и поддерживаемым способом?
— GreenAsJade

6
Это хакерское решение не так уж и плохо. Единственный вариант использования, который я вижу, - это тестирование, когда тестировщику нужно изменить дату.
— jacoor

2
просто предупреждение: этот хак испортил мне миграцию
— Дамио

16

В зависимости от ваших конкретных потребностей и любых нюансов в поведении вы можете сделать следующее:

from django.utils.timezone import now

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

Поле по умолчанию можно использовать следующим образом: 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.

Это не позволяет редактировать False


1
Я бы использовал from django.utils.timezone import nowвместо datetime.now, но это выглядит многообещающим.
— amjoconn

Спасибо, поменял.
— orblivion

Stackoverflow прекрасен, потому что некоторые ответы заставляют вас понять, что вы задали неправильный вопрос! Спасибо.
— Сэмюэл Дозон

5

Возможно, это связано с истинным значением auto_now_add. Возможно, вместо этого параметра для захвата даты при добавлении вы могли бы переопределить метод сохранения модели, чтобы вставить дату и время, когда идентификатор равен нулю.

class Rating(models.Model):

    ....
    def save(self, *args, **kwargs)
        if not self.id: 
            self.date = datetime.datetime.now()

Если да, то нет причин определять поле как auto_now
— FallenAngel

Не уверен, почему голос против; первая ссылка, которую предоставляет Шон Чин, указывает на аналогичный подход.
— Joe J

Это разумная альтернатива, если auto_nowне используется и editable=False. +1
— Шон Чин

3

Если вы хотите, чтобы какое-либо поле было видимым в списке всех ваших записей (когда вы нажимаете на модель в админке), а не при открытии этой конкретной записи, тогда -

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

admin.site.register(Rating, RatingAdmin)

«name» - ваше основное поле или любое другое поле, которое вы хотите отобразить в панели администратора.

Таким образом вы можете указать все столбцы, которые хотите видеть.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.