[Django]-Only showing year in django admin, a YearField instead of DateField?

32👍

I found this solution which solves the whole thing quite elegantly I think (not my code):

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)

Edit the range start to extend the list 🙂

8👍

Also, and this isn’t that relevant for your case, but is useful being aware of, don’t use datetime.date.today(), or datetime.datetime.now() as defaults. This is executed once, when the server is started up.

You are much better off passing the callables in:

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

Note, you could use a lambda to make it relative:

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

Of course, this is naive, and assumes there have been 5 leap years in the past 17 years.

7👍

For a solution not involving Model choices:

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>")

That’ll also create a placeholder in the input field with the value of help_text.

👤toxefa

6👍

You can also do this:

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)

I hope this will help you.

Leave a comment