Django模型动态选项:迁移时还是用户操作时求值?
代码
假设我有如下模型:
class Course(models.Model): title = models.CharField(max_length=48) YEAR_CHOICES = [(r, r) for r in range( datetime.date.today().year-1, datetime.date.today().year+2 ) ] year = models.IntegerField(_('year'), choices=YEAR_CHOICES)
问题
上述代码中的datetime.date.today()语句会在模型迁移时立即求值,还是在用户访问表单设置Course模型的year字段值时才求值?
换句话说,我的YEAR_CHOICES会固定在模型迁移时的年份,还是会随年份推移动态更新?
解答
求值时机:应用启动时,而非迁移或用户访问表单时
YEAR_CHOICES作为模型类的类属性,会在Django应用启动(比如执行runserver、启动WSGI服务器)时被立即求值计算,生成对应的年份范围列表。这个值会被缓存,直到应用重启才会重新计算。迁移不会固定年份,但应用启动后的年份会固定到启动时刻
迁移文件只会记录IntegerField的基本属性(比如字段类型、verbose_name等),不会保存choices的具体内容。但一旦应用启动,YEAR_CHOICES就固定为启动时的年份范围,之后哪怕跨年,只要不重启应用,选项都不会更新。实现动态更新的方法
如果想要年份选项随时间自动更新,不要直接用类属性定义choices,改用可调用函数来生成选项:
from datetime import date from django.db import models from django.utils.translation import gettext_lazy as _ def get_year_choices(): current_year = date.today().year return [(r, r) for r in range(current_year - 1, current_year + 2)] class Course(models.Model): title = models.CharField(max_length=48) year = models.IntegerField(_('year'), choices=get_year_choices)
这样每次需要加载选项(比如用户打开表单、后台验证数据)时,都会调用get_year_choices函数,实时计算当前的年份范围。
内容的提问来源于stack exchange,提问作者DevinG
相关产品推荐
相关产品推荐

