代码之家  ›  专栏  ›  技术社区  ›  odinho - Velmont

仅在django admin中显示年份,是一个YearField而不是DateField?

  •  28
  • odinho - Velmont  · 技术社区  · 15 年前

    我有一个模型,我需要存储出生年份。我用的是django管理员。使用此选项的人每天都会填写大量的人,DateField()显示的内容太多(对日期/月份不感兴趣)。

    class Person(models.Model):
      name = models.CharField(max_length=256)
      born = models.IntegerField(default=lambda: date.today().year - 17)
    

    正如你所看到的,大多数人都是17岁,所以我将他们的出生年份作为默认值。

    我能做得更好吗?我怎样才能用DateField生成YearField?如果制作一个YearField,我甚至可以制作一些“简单的标签”,比如日期的“现在”。(当然,在1989年、1990年、1991年和其他普通年份,专门的BornYearField会有简单的按钮)

    4 回复  |  直到 10 年前
        1
  •  29
  •   Nils Herde    6 年前

    我发现 this solution 我认为这非常优雅地解决了整个问题(不是我的代码):

    import datetime
    YEAR_CHOICES = []
    for r in range(1980, (datetime.datetime.now().year+1)):
        YEAR_CHOICES.append((r,r))
    
    year = models.IntegerField(_('year'), choices=YEAR_CHOICES, default=datetime.datetime.now().year)
    

        2
  •  8
  •   Matthew Schinckel    15 年前

    另外,这与您的案例无关,但有一点很有用,即不要使用datetime.date.today()或datetime.datetime.now()作为默认值。这在服务器启动时执行一次。

    您最好将可调用项传入:

    date = models.DateField(default=datetime.date.today)
    

    注意,可以使用lambda使其相对:

    date = models.DateField(default=lambda : datetime.date.today() - datetime.timedelta(days=6210))
    

    当然,这是幼稚的,并假设在过去17年中有5个闰年。

        3
  •  6
  •   Akseli Palén Greg Rogers    13 年前

    YEARS = (
        ("1990", "1990"),
        ("1991", "1991"),
        ("1992", "1992"),
        # P.e. generate a list from 1960 to date.today().year
        # The reason why they choice key and text value are the
        # same is that if you generate from 1960 to 2060 it will collide.
        #
        # E.g
        # from datetime import datetime
        # def tuplify(x): return (x,x)   # str(x) if needed
        # current_year = datetime.now().year
        # YEARS = map(tuplify, range(1930, current_year + 1))  # range(1,4) gives [1,2,3]
    )
    
    class Whatever(models.Model):
        # Show a list with years
        birthdate = models.IntegerField(max_length=2, choices=YEARS)
    

        4
  •  5
  •   toxefa    7 年前

    对于不涉及模型选择的解决方案:

    from django.core.validators import MinValueValidator, MaxValueValidator
    
    class Person(models.Model):
        year = models.PositiveIntegerField(
                validators=[
                    MinValueValidator(1900), 
                    MaxValueValidator(datetime.now().year)],
                help_text="Use the following format: <YYYY>")
    

    这还将在输入字段中创建一个值为的占位符 help_text