仅包含月份和年份的Django DateField

时间:2018-09-04 16:29:37

标签: django forms datefield

我之所以发布此信息,是因为找不到适合我的答案/示例,因此我以一种我在那里没有看过的方式解决了它。也许有用或可以讨论。

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

我首先开始使用一些JavaScript来做到这一点,然后使用Django自定义模型(将其归为models.DateField)。

后来我无法成功做到这一点(my post updated linked to this one) 由于有截止日期,我使用简单的ChoiceField将对象存储为Integers来完成此任务,然后使用@property方法从这些用户输入中建立正确的日期(每天加1)。

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

但是感谢@property,我仍然可以在Django模板中保留格式化日期和进行日期计算等便利。

models.py:

注意:如果无法在填充字段中构建日期,请使用此方法返回无,否则尝试在模板中呈现这些@property字段时将出现未绑定的错误。

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 }}

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

1 个答案:

答案 0 :(得分:0)

我认为您的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