【问题标题】:DateTimeField doesn't show in admin systemDateTimeField 不显示在管理系统中
【发布时间】:2011-09-17 04:31:25
【问题描述】:

我的“日期”字段怎么没有出现在管理系统中?

在我的 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。

有人知道吗?

【问题讨论】:

    标签: python django django-admin admin


    【解决方案1】:

    如果您真的想在管理面板中看到日期,可以在 admin.py 中添加readonly_fields:

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

    您指定的任何字段都将添加到可编辑字段之后。要控制顺序,您可以使用fields 选项。

    更多信息可从Django docs获得。

    【讨论】:

    • 这才是真正的答案!!
    • 如果您指定 fields,您还必须将您的字段放入其中,因此您在 readonly_fields 和 fields 中都需要它,否则该字段不会显示。跨度>
    • 我只是想指出,如果您使用的是fieldsets,这也适用,今天刚遇到这个问题。
    • 这将使该字段仅在我们单击并打开特定条目时出现。如果您希望该字段在列表视图本身中可见,则 stackoverflow.com/a/34966908/4440874
    • 请注意,我不确定为什么,但这似乎不适用于在 Django 1.9 下使用 auto_now_add=True 的 DateTimeFields。一种(某种)解决方法是将它们添加到 list_display 元组中。编辑:如果您也将字段添加到@BjornTipling 提到的fields,它将起作用。
    【解决方案2】:

    我相信原因在于auto_now_add 字段。

    来自this answer:

    具有 auto_now 属性的任何字段 set 也将继承 editable=False 因此不会出现在 管理面板。

    the docs中也提到过:

    按照目前的实施,设置 auto_now 或 auto_now_add 到 True 将 导致该字段具有可编辑=假 和空白=真设置。

    这是有道理的,因为如果在保存对象时该字段将被当前日期时间覆盖,则没有理由让该字段可编辑。

    【讨论】:

    • 虽然您确实应该能够在首次创建条目之后通过管理员编辑auto_now_add?
    • 您也应该能够在管理界面中简单地显示它,即使它是不可编辑的。
    • 请参考下面@hunger 的回答,了解如何在管理界面中将其显示为只读字段。
    • 如果该字段仅在创建对象时启动 (auto_now_add=True),则使该字段可编辑是有意义的。
    【解决方案3】:

    主要黑客:

    如果你真的需要这样做(就像我一样),你总是可以通过立即将字段设置为“可编辑”来定义字段,如下所示:

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

    这将使该字段可编辑,因此您可以实际更改它。它似乎工作正常,至少使用 mysql 支持引擎。我不能说其他后备存储是否会使这些数据在数据库中不可变,从而在尝试编辑时导致问题,因此请谨慎使用。

    【讨论】:

    • 不,不要这样做,使用 Hunger 描述的 readonly_fields 解决方案。
    • @GreenAsJade:一个理由会很好。
    • @mhsmith 使用 Hunger 的解决方案而不是这个的理由:因为这是一个主要的 hack 并且带有“谨慎使用”,而 Hunger 的解决方案使用 django 的设计方式。当您可以以合法且受支持的方式做您需要的事情时,为什么还要冒重大黑客攻击的风险?
    • 这个黑客解决方案还不错。但是我看到的唯一用例是测试 - 当测试人员需要更改日期时。
    • 只是一个警告:这个 hack 搞砸了我的迁移
    【解决方案4】:

    根据您的具体需求以及行为差异的任何细微差别,您可以执行以下操作:

    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

    【讨论】:

    • 我会使用from django.utils.timezone import now 而不是datetime.now,但这看起来很有希望。
    • 谢谢,我改了。
    • Stackoverflow 很棒,因为有些答案会让你意识到你没有问对问题!谢谢。
    • 感谢@orblivion,我在 django 中做项目已经很久了,但不知道这一点,再次感谢!
    【解决方案5】:

    这可能与 auto_now_add 为真有关。也许代替那个参数来捕获添加的日期,您可以覆盖模型保存方法以在 id 为空时插入日期时间。

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

    【讨论】:

    • 如果你这样做了,那么没有理由将字段定义为 auto_now
    • 不知道为什么投反对票; Shawn Chin 提供的第一个链接表明了类似的方法。
    • 这是一个明智的选择,假设 auto_now 未被使用且 editable=False。 +1
    【解决方案6】:

    如果您希望任何字段在所有条目的列表中可见(当您单击管理员中的模型时)而不是在您打开该特定条目时 -

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

    'name' 是您的主要字段或您希望在管理面板中显示的任何其他字段。

    这样你可以指定所有你想看到的列。

    【讨论】:

      【解决方案7】:

      你不能这样做,检查documentation

      auto_now 和 auto_now_add 都是 不可编辑 字段,您不能覆盖它们...

      【讨论】:

        【解决方案8】:

        只需在 admin.py 中的以下代码即可在 Django admin 中显示

        @admin.register(model_name)
        class model_nameAdmin(admin.ModelAdmin):
         list_display = ['date']
        
        Above code will display all fields in django admin that are mentioned in     'list_display', no matter the model field is set to 'True' for 'auto_now' attribute
        

        【讨论】:

          【解决方案9】:

          我想创建一个默认为当前时间的可编辑时间字段。

          我实际上发现最好的选择是完全避免使用auto_now 或auto_add_now,而只使用日期时间库。

          MyTimeField = models.TimeField(default=datetime.now)
          

          重要的是你应该让它成为变量now而不是一个函数/getter,否则你每次调用makemigrations时都会得到一个新的默认值,这将导致生成一堆冗余迁移。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-11-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-08-09
            • 2010-09-14
            相关资源
            最近更新 更多