上个月或下个月名称的Django模板标记

上个月或下个月名称的Django模板标记,django,django-templates,Django,Django Templates,我搜索了Django模板标签文档,没有找到一种简单的方法按名称显示日期的上个月或下个月。例如,假设日期为2015年12月1日,我希望能把下个月的名字“Jan”作为模板标签 为了找回年份,我可以这样做:{{selected_date | date:“Y”| add:“-1”}获取上一年 这似乎相当普遍,我认为该功能将在那里,而不必编写自定义标记。在模板上下文中提供下个月和上个月 但是,我认为您必须创建一个自定义过滤器来显示任意日期的下个月和上个月 为下一年/上一年添加一个过滤器可能是一个好主意-我

我搜索了Django模板标签文档,没有找到一种简单的方法按名称显示日期的上个月或下个月。例如,假设日期为2015年12月1日,我希望能把下个月的名字“Jan”作为模板标签

为了找回年份,我可以这样做:
{{selected_date | date:“Y”| add:“-1”}
获取上一年

这似乎相当普遍,我认为该功能将在那里,而不必编写自定义标记。

在模板上下文中提供
下个月
上个月

但是,我认为您必须创建一个自定义过滤器来显示任意日期的下个月和上个月


为下一年/上一年添加一个过滤器可能是一个好主意-我认为
{selected_date | previous_year}}
{{selected_date | date:“Y”| add:“-1”}
更清晰,谢谢您的回复。我没有在上下文中传递多个对象,而是编写了一个快速自定义模板标记,因为没有内置标记。这是我的样子

视图.py

#...
return render(request, 'index.html', 
              context={'selected_date': selected_date})  # As @Peter DeGlopper mentioned, alternative could have been to pass in  
import datetime

from django import template

register = template.Library()


@register.simple_tag(takes_context=True)
def get_next_month_name(context):
    selected_date = context['selected_date']
    next_month = selected_date.month % 12 + 1
    return datetime.date(1900, next_month, 1).strftime("%b")

@register.simple_tag(takes_context=True)
def get_prev_month_name(context):
    selected_date = context['selected_date']
    prev_month = selected_date.month - 1
    if prev_month == 0:
        prev_month = 12
    return datetime.date(1900, prev_month, 1).strftime("%b")

# As @Alasdair mentioned, can create additional tags for say 'previous_year' to make code cleaner
index.html

{% load template_extras %}

<label>{% get_prev_month_name %}</label>
<label>{% get_next_month_name %}</label>
注意:更改模板标签代码时不要忘记重新启动服务器,将应用程序添加到
settings.py
中已安装的\u APPS变量中,并在templatetags文件夹中添加
\uu init\uuuuuu.py
(如果是Python 2)。

您还可以使用Python根据给定日期计算上个月或下个月

from dateutil.relativedelta import relativedelta
from django import template

register = template.Library()


def calculate_date(date, **kwargs):
    """
    Performs date calculation based on an interval.
    Args:
        date (datetime object): The date to which the interval is calculated to.
        **kwargs: Accepts a relative time interval with a positive or negative
            integer to determine if we will add or subtract to the date.
    """
    return date + relativedelta(**kwargs)

@register.assignment_tag
def get_previous_month(selected_date):
    return calculate_date(selected_date, months=-1).strftime("%b")

@register.assignment_tag
def get_next_month(selected_date):
    return calculate_date(selected_date, months=+1).strftime("%b")

如果我没记错的话,覆盖日期范围的归档默认视图通过在上下文中传递多个日期对象来实现这一点——这可能也是我要做的。否则,您可以编写一个自定义筛选器来完成此操作-我认为没有内置的筛选器。如果您要手动计算它,我喜欢通过添加或减去适当的
timedelta
来完成此操作,而不是使用模运算或If语句来处理环绕情况。例如,如果您的
所选日期
是任意月份的第一个,请添加
时间增量(天=31)
以确保您在下个月,然后
替换(天=1)
将该日期设置为第一个。或者减去
timedelta(days=1)
得到上个月的最后一天,然后
replace
(如果需要)。