首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django的年份农田

Django的年份农田
EN

Stack Overflow用户
提问于 2018-03-01 13:44:24
回答 4查看 30.4K关注 0票数 21

我希望我的用户输入他们的出生年份。我不希望他们在表单中输入相同的内容,而是从可用的选项中选择年份。我知道,如果我需要日期而不是年份,我可以在我的模型中做这样的事情:

代码语言:javascript
复制
class MyModel(models.Model):

    birthday = models.DateField(null=True, blank=True)

我可以在表单中这样做,让用户从数据报警器中选择日期。

代码语言:javascript
复制
    birthday = forms.fields.DateField(widget=forms.widgets.DateInput(attrs={'type': 'date'}))

一年来,我可以使用CharField/IntegerFieldchoices,类似于在这个所以答案中所做的工作。

代码语言:javascript
复制
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年的变化不会改变现有的选择。

你能帮助或提供提示来实现我想做的事吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-03-01 13:57:07

我最初的想法是编写一个可调用的函数,返回选项,并对每个请求进行评估。

代码语言:javascript
复制
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的检查框架不允许将year_choices用作缺省值。即使您可以对要动态生成的选项进行黑客攻击,但这样做的缺点是Django每年都会尝试在选择发生变化时创建迁移。

您可以通过在表单级别生成选择来避免这种情况。您可以在模型中使用验证器来防止无效数据。请注意,MaxValueValidator封装在一个函数max_value_current_year中,以避免每年进行新的迁移。

代码语言:javascript
复制
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)
票数 35
EN

Stack Overflow用户

发布于 2018-03-01 14:02:26

您可以使用IntegerField min_valuemax_value将选项(年份)放在表单中。在模型中,您可以使用没有选择的IntegerField。

因此,您不会担心年份的变化,因为您只会更改表单中的选项。

如果您想自动更改年份,这可能会帮助您:值在运行时

票数 6
EN

Stack Overflow用户

发布于 2019-02-20 17:13:51

对于那些不喜欢长选择字段的人,比如@Alasdair解决方案,想象一下从1984到2019年有一个选择字段,这样长的选择列表。如果有一个字段,您可以输入年份,但仍然有增加或减少的方法。要解决这个问题,请将models.PositiveIntegerField与MinValueValidator和MaxValueValidator结合使用,如下所示:

代码语言:javascript
复制
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])
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49051017

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档