You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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会固定在模型迁移时的年份,还是会随年份推移动态更新?

解答
  1. 求值时机:应用启动时,而非迁移或用户访问表单时
    YEAR_CHOICES作为模型类的类属性,会在Django应用启动(比如执行runserver、启动WSGI服务器)时被立即求值计算,生成对应的年份范围列表。这个值会被缓存,直到应用重启才会重新计算。

  2. 迁移不会固定年份,但应用启动后的年份会固定到启动时刻
    迁移文件只会记录IntegerField的基本属性(比如字段类型、verbose_name等),不会保存choices的具体内容。但一旦应用启动,YEAR_CHOICES就固定为启动时的年份范围,之后哪怕跨年,只要不重启应用,选项都不会更新。

  3. 实现动态更新的方法
    如果想要年份选项随时间自动更新,不要直接用类属性定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:54:56