Inq*_*abi 9 python django django-models
我希望我的用户进入他们的出生年份.我不希望他们在表单中键入相同的内容,而是从可用选项中选择年份.我知道如果我需要约会而不是一年,我可以在我的模型中做这样的事情:
class MyModel(models.Model):
birthday = models.DateField(null=True, blank=True)
Run Code Online (Sandbox Code Playgroud)
我可以在表单中执行此操作,让用户从datepicker中选择日期.
birthday = forms.fields.DateField(widget=forms.widgets.DateInput(attrs={'type': 'date'}))
Run Code Online (Sandbox Code Playgroud)
对于今年,我可以用一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)
Run Code Online (Sandbox Code Playgroud)
然而,问题是,从2018年到2019年,当前年度的变化不会改变现有的选择.
你能帮忙或提供一些提示来实现我想做的事吗?
Ala*_*air 15
我最初的想法是编写一个返回选项的callable,它将针对每个请求进行评估.
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)
Run Code Online (Sandbox Code Playgroud)
但是这不起作用,因为Django的检查框架不允许将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)
Run Code Online (Sandbox Code Playgroud)
你可以把选项(年)的形式,使用IntegerField MIN_VALUE和MAX_VALUE。在模型中,您可以不加选择地使用IntegerField。
因此,您不必担心年份何时更改,因为您只会更改表单中的选项。
如果您想自动更改年份,这可以帮助您:Django forms integerField set max_value on runtime
对于那些不喜欢在@Alasdair 解决方案中使用长选择字段的人,想象一下从 1984 年到 2019 年有一个选择字段,如此长的选择列表。如果有一个字段,您可以输入年份并且仍然可以增加或减少。要以我的方式解决这个问题,请使用带有 MinValueValidator 和 MaxValueValidator 的 models.PositiveIntegerField,如下所示:
import datetime
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
def current_year():
return datetime.date.today().year
def max_value_current_year(value):
return MaxValueValidator(current_year())(value)
class EmployeesTrainings(models.Model):
name = models.ForeignKey(employee, default='', blank=True, null=True, on_delete=models.CASCADE)
training_name = models.TextField(max_length=200, default='', blank=False, null=False)
training_year = models.PositiveIntegerField(
default=current_year(), validators=[MinValueValidator(1984), max_value_current_year])
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7999 次 |
最近记录: |