PAYATHON 2026

Django model choices 会在每次请求时增加负载吗?

数据小许

结论

把 CATEGORY_CHOICES 和 DISTRICT_CHOICES 定义为模型类上的静态 Python 数据,再由视图传给模板,通常不会让每次请求都产生数据库查询。模板遍历这些选项时也不会访问数据库。

这些选项在模型类定义时随 Python 模块加载而创建,之后由当前进程中的模型类持有并复用。Web 服务有多个 worker 进程时,每个进程都会各自加载应用代码,但页面请求不会因此重新查询选项。

为什么不会触发数据库查询

视图传入的是模型类属性:

categories = AdPost.CATEGORY_CHOICES
districts = AdPost.DISTRICT_CHOICES

这两项是 Python 列表。模板循环读取传入的数据:

{% for key, label in districts %}
<option value="{{ key }}">{{ label }}</option>
{% endfor %}

这里没有 QuerySet,也没有执行数据库查询的代码。旧写法中的 AdPost.objects.filter(...).values_list(...).distinct() 则会查询数据库;如果视图每次请求都执行这段代码,数据库就会处理该查询。

何时适合使用静态 choices

如果分类和地区是预先定义、较少变化的固定选项,可以继续使用静态 choices:

class AdPost(models.Model):
    CATEGORY_CHOICES = [
        ('fish', 'fish'),
        ('cow', 'cow'),
    ]
    DISTRICT_CHOICES = [
        ('e', 'e'),
        ('j', 'j'),
    ]

    category = models.CharField(max_length=50, choices=CATEGORY_CHOICES)
    district = models.CharField(max_length=30, choices=DISTRICT_CHOICES)

视图可以直接传递这些选项:

categories = AdPost.CATEGORY_CHOICES
districts = AdPost.DISTRICT_CHOICES

如果管理员需要增删选项,或选项必须根据当前数据库记录动态变化,就应从数据库读取相应数据。静态 choices 不会自动包含数据库中新增加的地区或分类;维护这些选项时,需要同步更新代码,并按项目流程部署。

注意事项

choices 为字段提供可用选项,可用于表单等场景中的选择和校验;它不会让模板渲染自动访问数据库。如果搜索表单还有其他 QuerySet 或查询逻辑,那些部分仍可能产生数据库查询,需要分别检查。

固定地区和分类选项适合使用静态 choices。动态数据则仍需从数据库读取。

备注:内容仅供参考。