Показывать только год в админке django, а YearField вместо DateField?
У меня есть модель, где мне нужно хранить год рождения. Я использую админку django. Человек, использующий это, будет заполнять множество людей каждый день, и DateField() показывает слишком много (не интересует день / месяц).
Это модель макета, показывающая, как она выглядит сейчас:
class Person(models.Model):
name = models.CharField(max_length=256)
born = models.IntegerField(default=lambda: date.today().year - 17)
Как видите, большинству людей по 17 лет, поэтому по умолчанию у меня год рождения.
Могу ли я сделать это лучше? Как я могу сделать YearField из DateField? При создании YearField я могу даже сделать несколько "простых тегов", таких как "сейчас", которые есть у этой даты. (Конечно, специализированный BornYearField будет иметь удобные кнопки для 1989, 1990, 1991 и других обычных лет)
4 ответа
Я нашел это решение, которое решает все это довольно элегантно, я думаю (не мой код):
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)
Отредактируйте диапазон начала, чтобы расширить список:-)
Кроме того, и это не так важно для вашего случая, но полезно знать, не используйте datetime.date.today() или datetime.datetime.now() по умолчанию. Это выполняется один раз, когда сервер запускается.
Вам гораздо лучше передать вызовы в:
date = models.DateField(default=datetime.date.today)
Обратите внимание, вы можете использовать лямбду, чтобы сделать ее относительной:
date = models.DateField(default=lambda : datetime.date.today() - datetime.timedelta(days=6210))
Конечно, это наивно и предполагает, что за последние 17 лет было 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>")
Это также создаст заполнитель в поле ввода со значением help_text
,
Вы также можете сделать это:
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)
Я надеюсь, что это поможет вам.