只有月份和年份的 Django DateField

Posted

技术标签:

【中文标题】只有月份和年份的 Django DateField【英文标题】:Django DateField with only month and year 【发布时间】:2019-02-09 17:44:29 【问题描述】:

我发布此内容是因为我找不到令我满意的答案/示例,并且我以一种我没有读过的方式解决了它。也许它可以有用或可以讨论。

基本上,我的应用程序会显示用户可以在其中创建对象的表单集。一旦验证,表单集将再次显示,用户可以添加新对象。 指定日期无关紧要。

我首先开始使用一些 javascript 来做这件事,然后使用 Django 自定义模型(子类化 models.DateField)。

我无法成功地使用后者 (my post updated linked to this one) 因为我有截止日期,所以我使用简单的 ChoiceField 将对象存储为整数,然后使用 @property 方法从这些用户输入中构建一个正确的日期(添加 1 作为天)。

这样我就避免了深入研究 Django 蒸汽管道,甚至摆脱了日期选择器!

但是感谢@property,我仍然可以方便地在Django模板中格式化日期并进行日期计算等......

models.py:

注意:如果日期不能由填充的字段构建,则使用返回 None,否则在尝试在模板中呈现这些 @property 字段时会出现未绑定错误。 p>

class MyModel(models.Model):

    YEAR_CHOICES = [(y,y) for y in range(1968, datetime.date.today().year+1)]
    MONTH_CHOICE = [(m,m) for m in range(1,13)]

    start_year = models.IntegerField(choices=YEAR_CHOICES,
                 default=datetime.datetime.now().year,)
    start_month = models.IntegerField(choices=MONTH_CHOICE,
                  default=datetime.datetime.now().month,)
    end_year = models.IntegerField(choices=YEAR_CHOICES,
               default=datetime.datetime.now().year,)
    end_month = models.IntegerField(choices=MONTH_CHOICE,
                default=datetime.datetime.now().month,)

    @property
    def start_date(self):
        if self.start_year and self.start_month:
            return datetime.date(self.start_year, self.start_month, 1)
        elif self.start_year:
            return datetime.date(self.start_year, 12, 31)
        else:
            return None

    @property
    def end_date(self):
        if self.end_year and self.end_month:
            return datetime.date(self.end_year, self.end_month, 1)
        elif self.end_year:
            return datetime.date(self.end_year, 12, 31)
        else:
            return None

forms.py

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        exclude = ("blabla",)

现在,如果您想在表单模板中显示日期,您可以使用:

 form.instance.start_date 

希望对您有所帮助,欢迎提出建议!

【问题讨论】:

这是一个MonthField 实现:django-monthfield 【参考方案1】:

我不太清楚,你到底在做什么? 如果你想显示一个只有年份和月份的日期字符串。这可以通过使用模板过滤器date 和格式来实现,例如: obj.created_at|date:'%y %m'

但是如果我错了,您可能想在您的模型表单中自定义一个文件来选择一个日期(只有年和月),那么您已经做过的事情就是这个想法,但代码是问题

【讨论】:

我的意思是你的模型中可以有一个正常的日期时间(或日期)字段,但控制应该在 html 页面中打印的内容【参考方案2】:

我认为您的start_dateend_date 功能需要更改:

def start_date(self):
    if self.start_year and self.start_month:
        return datetime.date(self.start_year, self.start_month, 1)
    elif self.start_year:
        # return Jan 1st
        return datetime.date(self.start_year, 1, 1)
    else:
        return None

def end_date(self):
    if self.end_year and self.end_month:
        if self.end_month == 12:
            # if month is December, return December 31st
            return datetime.date(self.end_year, self.end_month, 31)
        else:
            # else, get first day of next month and subtract 1 day.
            return datetime.date(self.end_year, self.end_month+1, 1) - datetime.timedelta(days=1)
    elif self.end_year:
        return datetime.date(self.end_year, 12, 31)
    else:
        return None

【讨论】:

以上是关于只有月份和年份的 Django DateField的主要内容,如果未能解决你的问题,请参考以下文章

Django ModelForm 日期验证

为 Django 存档页面选择不同的年份和月份

Django - 非连续月份

Bootstrap Datepicker - 只有月份和年份不起作用

Django Rest Framework django_filters 返回空列表

没有日期选择的角度日期选择器(只有月份和年份)