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。动态数据则仍需从数据库读取。
备注:内容仅供参考。
