Otree同页面实现基于前置问题答案的条件性提问
在Otree中实现同一页面的条件性提问
需求说明
需要在同一页面实现以下逻辑:
- 问题1:您的主要职业是什么?
- 选项:A. 在职工作、B. 学生、C. 失业
- 问题2:仅当问题1选A时显示,内容为“您所在的行业是?”
- 选项:A. 交通运输、B. 采矿、C. 其他
您当前已实现分页面的条件显示效果,现需将两个问题合并到同一页面。
实现方案
1. 修改Python核心代码
调整页面类与模型字段,将两个问题放到同一页面,并添加后端验证逻辑:
from otree.api import * doc = """ 同一页面的条件性提问 """ class C(BaseConstants): NAME_IN_URL = 'conditional_question' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): occupation = models.StringField( label='您的主要职业是什么?', choices=[ ('Work', 'A. 在职工作'), ('Student', 'B. 学生'), ('Unemployment', 'C. 失业') ] ) industry = models.StringField( label='您所在的行业是?', choices=[ ('transportation', 'A. 交通运输'), ('mining', 'B. 采矿'), ('others', 'C. 其他') ], blank=True # 允许暂不填写,后续通过验证控制必填逻辑 ) # PAGES class ConditionalPage(Page): form_model = 'player' form_fields = ['occupation', 'industry'] @staticmethod def error_message(player: Player, values): # 后端验证:选择在职工作时必须填写行业 if values['occupation'] == 'Work' and not values['industry']: return '请填写您所在的行业' page_sequence = [ConditionalPage]
2. 添加自定义页面模板
在你的app目录下创建templates/conditional_question/ConditionalPage.html(路径需匹配你的app名称),写入以下内容实现前端动态显示逻辑:
{% extends "global/Page.html" %} {% load otree static %} {% block title %} 职业与行业调查 {% endblock %} {% block content %} {% formfield player.occupation %} <div id="industry-container" style="display:none;"> {% formfield player.industry %} </div> {% next_button %} <script> // 监听职业选择的变化,动态控制行业问题显示/隐藏 document.getElementById('id_occupation').addEventListener('change', function() { const industryContainer = document.getElementById('industry-container'); if (this.value === 'Work') { industryContainer.style.display = 'block'; } else { industryContainer.style.display = 'none'; // 隐藏时清空行业选项,避免提交无效值 document.getElementById('id_industry').value = ''; } }); // 页面加载时初始化显示状态(适配页面刷新场景) window.onload = function() { const occupationSelect = document.getElementById('id_occupation'); const industryContainer = document.getElementById('industry-container'); if (occupationSelect.value === 'Work') { industryContainer.style.display = 'block'; } }; </script> {% endblock %}
3. 关键逻辑说明
- 前端交互:通过JavaScript监听下拉框的
change事件,实时切换行业问题的显示状态,同时在隐藏时清空选项值,避免冗余数据提交。 - 后端验证:添加
error_message方法,确保用户选择“在职工作”时必须填写行业,防止前端逻辑被绕过。 - 初始状态处理:页面加载时自动检查当前职业选择,确保刷新页面后显示状态正确。
内容的提问来源于stack exchange,提问作者CAMG
相关产品推荐
相关产品推荐

