Django中的Year字段
我希望我的用户输入他们的出生年份。我不希望他们在表格中键入相同的内容,而是从可用选项中选择年份。我知道如果需要日期而不是年份,可以在模型中执行以下操作:
class MyModel(models.Model):
birthday = models.DateField(null=True, blank=True)
我可以使用表格来执行此操作,以使用户从datepicker中选择日期。
birthday = forms.fields.DateField(widget=forms.widgets.DateInput(attrs={'type': 'date'}))
对于一年,我可以使用CharField/IntegerField
与choices
该SO答案中类似的方法。
import datetime
YEAR_CHOICES = [(r,r) for r in range(1984, datetime.date.today().year+1)]
year = models.IntegerField(_('year'), choices=YEAR_CHOICES, default=datetime.datetime.now().year)
但是,问题在于当前年度从2018年更改为2019年不会更改可用选项。
您能帮我实现我想做的事情吗?
-
我最初的想法是编写一个可返回选择的可调用对象,该选择将针对每个请求进行评估。
import datetime def year_choices(): return [(r,r) for r in range(1984, datetime.date.today().year+1)] def current_year(): return datetime.date.today().year class MyModel(models.Model): year = models.IntegerField(_('year'), choices=year_choices, default=current_year)
但是,这不起作用,因为Django的check框架不允许将year_choices用作默认值。即使您可以破解要动态生成的选择,它也会具有Django每年都会在选择更改时尝试创建迁移的缺点。
您可以通过在表单级别生成选择来避免这种情况。您可以在模型中使用验证器来防止无效数据。请注意,
MaxValueValidator
该函数包含在函数中,max_value_current_year
以避免每年重新迁移。import datetime from django.core.validators import MaxValueValidator, MinValueValidator def current_year(): return datetime.date.today().year def max_value_current_year(value): return MaxValueValidator(current_year())(value) class MyModel(models.Model): year = models.IntegerField(_('year'), validators=[MinValueValidator(1984), max_value_current_year]) def year_choices(): return [(r,r) for r in range(1984, datetime.date.today().year+1)] class MyForm(forms.ModelForm): year = forms.TypedChoiceField(coerce=int, choices=year_choices, initial=current_year)