Django:如何仅按年份过滤日期时间字段?

24 投票
3 回答
27063 浏览
提问于 2025-04-15 23:41

我正在尝试创建一个Django页面,列出所有按创建年份分类的条目。比如说:

2010年:

  • 笔记 4

  • 笔记 5

  • 笔记 6

2009年:

  • 笔记 1

  • 笔记 2

  • 笔记 3

这比我想象的要难得多。下面是数据来源的模型:

class Note(models.Model):
    business = models.ForeignKey(Business)
    note = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    class Meta:
        db_table = 'client_note'

    @property
    def note_year(self):
        return self.created.strftime('%Y')

    def __unicode__(self):
        return '%s' % self.note

我尝试了几种不同的方法,但每条路上都遇到了障碍。我猜一个有效的“分组”方法可以解决这个问题(使用PostGres数据库),但我找不到任何支持这个功能的Django方法。我试着从数据库中获取单独的年份,但我发现很难仅通过年份值来过滤日期时间字段。最后,我尝试添加note_year这个属性,但因为它是派生的,我无法过滤这些值。

有没有什么优雅的方法可以做到这一点?我觉得这应该很简单,但我遇到了很多麻烦。任何建议都非常感谢。

3 个回答

1

我们可以通过使用一个年份列表来改进过滤器,然后检查创建年份是否在这个列表里。

这样一来,数据库只会被调用一次,因为 Note.objects.filter 会在 for 循环外运行。

大概是这样的:

notes = Note.objects.all().dates('created', 'year')
years = [note.year for note in notes]

Note.objects.filter(created__year__in = years)
3

你可以使用 django.views.generic.date_based.archive_year 这个功能,或者使用 year 字段查找。

47

你可以自己写SQL语句,或者使用

date_list = Note.objects.all().dates('created', 'year')

for years in date_list:
    Note.objects.filter(created__year = years.year)

这就是在基于日期的通用视图中处理的方式。

撰写回答