只在django admin中显示年份,YearField而不是DateField?

odi*_*ont 28 django datetime django-admin datefield

我有一个模型,我需要存储出生年份.我正在使用django admin.使用它的人每天都会填满大量的人,而DateField()显示太多(对日/月不感兴趣).

这是一个模型模型,显示它现在如何:

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

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

我能做得更好吗?如何从DateField中创建YearField?如果制作一个YearField我甚至可以制作一些"简单的标签",就像日期那样的"现在".(当然,一个专门的BornYearField将有1989,1990,1991和其他常见年份的简单按钮)

Nil*_*rde 27

我找到了这个解决方案,我认为(不是我的代码)非常优雅地解决了整个事情:

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)
Run Code Online (Sandbox Code Playgroud)

编辑范围开始扩展列表:-)

  • 你可以把它全部放在一行:`YEAR_CHOICES = [(r,r)for r in range(1984,datetime.date.today().year + 1)]` (14认同)
  • 默认值可能看起来像 `default=lambda: datetime.datetime.now().year` 否则它只会在服务重新启动时更新默认值 (2认同)
  • 另外,如果你希望迁移工作,那么你不能使用 lambda,所以你需要定义一个简单的函数 `def current_year(): ...` 并使用它(不带括号)代替 `default=current_year ` (2认同)

Mat*_*kel 9

此外,这与您的情况无关,但是有用的是,请不要使用datetime.date.today()或datetime.datetime.now()作为默认值.服务器启动时执行一次.

传递callables比你好多了:

date = models.DateField(default=datetime.date.today)
Run Code Online (Sandbox Code Playgroud)

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

date = models.DateField(default=lambda : datetime.date.today() - datetime.timedelta(days=6210))
Run Code Online (Sandbox Code Playgroud)

当然,这是天真的,并假设在过去的17年中已经有5个闰年.

  • 仅仅是我或者这个得到满足的答案不是关于这个问题吗? (11认同)

Osc*_*lal 6

你也可以这样做:

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)
Run Code Online (Sandbox Code Playgroud)

我希望这能帮到您.


tox*_*efa 5

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

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>")
Run Code Online (Sandbox Code Playgroud)

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