我正在通过otree构建一个实验室实验,“一个基于Django的框架,用于实现多人决策策略游戏。”
关于otree形式的基础知识
以下是otree如何让玩家报告其选择的示例(基于“match_pennies”游戏,该游戏是otree提供的模板的一部分)。
在名为的文件中model.py
,可以找到以下代码
class Player(otree.models.BasePlayer):
[...]
penny_side = models.CharField(choices=['Heads', 'Tails'])
[...]
然后在views.py
一个发现
class Choice(Page):
form_model = models.Player
form_fields = ['penny_side']
最后,choice.html
通过插入将表单显示给最终用户
{% formfield player.penny_side with label="I choose:" %}
我想做什么
创建一个灵活的实验,其中玩家必须做出的选择数量随参数而变化x
。也就是说,我希望整个框架x
只需设置一个参数即可生成可能的选择x
,而不必手动更新所有文件。这是为了让我的生活更轻松,如果我们改变实验设计,并使代码对其他具有不同实验设计的人有用(我计划在某些时候在Github上发布它)。
看起来使用几个循环似乎相当容易,但是我在使用列表方面遇到了问题otree
。
根据我的理解,我只看到一种非常讨厌的方式,让选择的数量取决于参数x
。我首先给每个选择一个不同的名字model.py
,例如
class Player(otree.models.BasePlayer):
[...]
for i in range(x):
exec("""choice%d = models.IntegerField(
choices= ['Heads','Tails'])""" %i)
[...]
然后将所有这些选择的名称传递给view.py
,例如
class Choice(Page):
all_forms = list()
for i in range(x):
all_forms.append('choice%d' %i)
form_model = models.Player
form_fields = all_forms
最后,找到一种方法来遍历Choice.html中的所有表单; 类似的东西(我知道下面的代码不起作用,只是为了给出它的要点)
{% for p in range(x) %}
{% formfield player.choice{{p}} with label="I choose:" %}
{% endfor %}
我的问题是:
- 这一切都很脏,看起来过于复杂:已经发明了列表以避免这种疯狂的命名过程。您是否看到了使用列表进行此操作的方法?
- 如果这是攻击otree的唯一方法,并且数字选择取决于参数
x
,那就这样吧。但我仍然无法找到通过Django循环生成所需表单集的方法(显然上面的例子不起作用,原因很多。)。