我可以在我的Django模型中成功过滤给定年份,但我找不到列出有效年份的方法,以便用户可以访问它们。
我有一个带有定义的'datetime'字段的django模型,因此最初命名为'date'。在我的模板中,我可以成功访问'bar.date.date.year'字段,因此我知道它存在,但是当我尝试以下函数时...
blog_years=[]
for entry in blog_entries:
if entry.date.date.year not in blog_years:
blog_years.append(entry.date.date.year)
我被告知“'builtin_function_or_method'对象没有属性'year'”
我只能假设我嘲笑我不熟悉的Python的某些方面,但我无法弄清楚它是什么。我很确定它必须是语法,但过去那个..
答案 0 :(得分:14)
Django有一种优雅而有效的方式。您可以查看他们的文档https://docs.djangoproject.com/en/1.9/ref/models/querysets/#dates 但要重温它
Entry.objects.dates('pub_date', 'year')
这将在查询中显示不同的年份值。
答案 1 :(得分:6)
如果您使用的是postgres,则可以
BlogEntry.objects.extra(select={"year": "EXTRACT(YEAR FROM date)"}).distinct().values_list("year", flat=True)
答案 2 :(得分:3)
第一个.date
访问日期时间对象。
第二个.date
正在访问datetime对象上的方法,该方法返回日期对象但不调用它(此步骤是不必要的)。
最后一部分(您编写它的方式)是尝试访问日期方法的year
属性,而不是访问结果的year
属性日期方法调用。
更正代码以查看差异,它看起来像这样......
blog_years=[]
for entry in blog_entries:
if entry.date.date().year not in blog_years:
blog_years.append(entry.date.date().year)
但你应该做的更像是......
blog_years=[]
for entry in blog_entries:
if entry.date.year not in blog_years:
blog_years.append(entry.date.year)
因为datetime对象也有date属性。
答案 3 :(得分:3)
Python set
不允许重复,所以如果你想要一份不同年份的列表:
blog_years = list(set([entry.date.year for entry in blog_entries]))
或者,您可以使用distinct()
:
blog_years = blog_entries.distinct(entry__date__year).values(entry__date__year)
当然,请根据您的型号调整以上内容。
答案 4 :(得分:1)
date()
是datetime
的方法,使用
blog_years=[]
for entry in blog_entries:
if entry.date.date().year not in blog_years:
blog_years.append(entry.date.date().year)
答案 5 :(得分:1)
来自django 1.10它变得非常简单
foo.
答案 6 :(得分:0)
它可能不是你期望的(它可以在没有博客帖子的情况下返回几年):
from datetime import date
from django.db.models import Min
def blog_years():
current_year = date.today().year
queryset = Entry.objects.annotate(Min('date')).order_by('date')
if queryset:
oldest_year = queryset[0].date.date().year
else:
oldest_year = current_year
return range(oldest_year, current_year + 1)