【问题标题】:Django admin: rendering page to add new object fails only when datetime field is included in fieldsetDjango admin:仅当字段集中包含日期时间字段时,渲染页面以添加新对象才会失败
【发布时间】:2016-01-20 11:51:40
【问题描述】:

我一直在开发一个 Django 应用程序来替换我和一些朋友一起玩的基于电子表格的体育选择游戏。不久前我定义了我的游戏模型,但最近添加了一个日期时间字段来表示游戏/比赛的开始时间:

class Game(models.Model):
  home_team = models.CharField(max_length=100, default='---')
  away_team = models.CharField(max_length=100, default='---')
  spread = models.FloatField(default=0)    
  week = models.IntegerField(default=0)
  home_team_score = models.IntegerField(default=0)
  away_team_score = models.IntegerField(default=0)
  start_time = models.DateTimeField(default='2015-09-01 13:00:00')

  def has_started(self):
    if datetime.now() >= self.start_time:
        return True
    return False
  def __str__(self):
    return '%s vs. %s, week: %i' % (self.home_team, self.away_team, self.week)

我刚刚注意到,当我使用 Django 管理功能添加新游戏时,创建页面会出错。但是,如果我点击现有游戏,页面显示正常,我可以按预期编辑开始时间。

抛出的错误是:

 AttributeError at /admin/app/game/add/
'str' object has no attribute 'date'

一些搜索返回了类似的问题,但它们与使用 auto_nowauto_now_add 将日期时间字段定义为 True 有关,因此修复方法是确保它将这些字段作为只读字段处理。

这种情况不同,好像我在admin.py中定义了一个自定义的fieldset,不包含时间字段,点击添加新的时候创建页面不会出错。例如:

class GameAdmin(admin.ModelAdmin):
  fieldsets = [
    ('League week', {'fields': ['week'], }),
    ('Teams',       {'fields': ['home_team', 'away_team'], }),
    ('Spread',      {'fields': ['spread'], }),
              ]

  list_filter = ['week']
  search_fields = ['home_team','away_team']

这可以很好地添加一个新游戏,我可以回到默认的管理布局来更改默认时间。

我认为我可能需要从日期时间导入日期,但添加它并没有帮助。为了正确处理日期,我需要以不同的方式定义我的字段集吗?

【问题讨论】:

  • 尝试将start_timedefault 属性设置为datetime.datetime 的对象,即datetime.datetime.now() 或在您的情况下为datetime.datetime(year=2015, month=9, day=1, hours=13)
  • 谢谢您-完美!我想我认为自动解析字符串会很好的假设并不完全正确。如果您将其添加为答案,我会尽快接受。

标签: python django datetime django-admin


【解决方案1】:

start_time 的默认属性设置为datetime.datetime 的对象,即datetime.datetime.now() 或在您的情况下

datetime.datetime(year=2015, month=9, day=1, hours=13)

尽管通过设置使用当前/动态时间作为default 被认为是一种好习惯

default = datetime.datetime.now

default = django.utils.timezone.now

对于时区感知日期时间(请参阅 .now 之后不存在括号 ()),但这取决于您的用例。

【讨论】:

  • 注意最佳实践 - 正如您可能猜到的那样,我当前的默认值是占位符,我还将添加典型的创建/修改字段,它们都默认为 now
猜你喜欢
  • 2022-01-26
  • 1970-01-01
  • 2019-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-27
  • 2012-12-31
相关资源
最近更新 更多