oTree中的每个页面都可以包含一个表单,玩家应通过单击“下一步”按钮填写并提交该表单。要创建表单,首先需要Player在models.py中的类中使用字段。然后,在您的Page类中,设置form_modelform_fields

例如,这是models.py:

和pages.py:

当用户提交表单时,提交的数据将自动保存到玩家模型上的相应字段中。

(您也可以设置form_model ='group'而不是player;请参阅form_model ='group'。)

在2018年1月,语法从form_model = models.Player更改为form_model ='player'。 有关更多信息,请参阅oTree 2.0。

模板中的表单

在模板中,您可以显示表单。{% formfields %}

{% formfields %} 于2018年6月推出。它相当于:

如果要单独定位字段,可以改为使用:{% formfield %}

您也可以将直接放在模板中:

注意:如果您之前编写过HTML表单,则可能习惯于编写<input>元素,例如: <input type =“text”name =“contribution”>。 在oTree中,通常使用formfield更容易。 它将自动生成正确的<input> HTML,以及CSS样式,标签和错误消息。 但是,如果您想要更灵活,可以自由编写原始HTML。 请参阅高级:原始HTML小部件。

form_model = ‘group’

如果你设置form_model ='group'。 用户提交的值将存储在组模型中,而不是玩家中。 这在一些玩家代表小组做出决定的游戏中通常很有用。 例如,在最后通牒博弈实验中,玩家1提出要求而玩家2接受或拒绝。 由于每组只提供1个要求,您可以在组中定义字段:

您的页面如下所示:

在您的模板中,您将拥有:

简单的表单字段验证

玩家必须在进入下一页之前提交有效表格。如果他们提交的表单无效(例如缺失或不正确的值),则会将其重新显示给他们以及他们需要纠正的错误列表。

oTree自动验证输入。 例如,如果您有一个包含IntegerField的表单,oTree将拒绝输入,如1.5或hello。

最小和最大

例如,这是你需要一个12到24之间的整数:

如果最大/最小值未修复,则应使用{field_name} _max()

选择

如果您希望字段为包含选项列表的下拉菜单,请设置choices=

要使用单选按钮而不是下拉菜单,您应该将小部件设置为RadioSelect或RadioSelectHorizontal:

如果需要动态确定选择列表,请使用{field_name} _choices()

您还可以通过列出[value,display]对来为每个选项设置显示名称:

如果您这样做,用户只会看到“低”,“中”,“高”的菜单,但他们的回复将被记录为1,2或3。

设置字段后,您可以使用get_FOO_display访问人类可读的名称,如下所示:self.get_level_display()#return,例如: '中'。 但是,如果使用{field_name} _choices()动态定义选项,为了使用get _ * _ display(),还需要在models.py中的Player / Group上定义* _choices方法。

可选字段

如果字段是可选的,您可以这样使用blank=True

然后HTML字段将没有该required属性。

动态表单字段验证

minmaxchoices上面描述仅用于固定的(恒定)值。

如果您希望动态确定它们(例如,不同于玩家),那么您可以在Page类中定义以下方法之一pages.py

{field_name} _choices()

就像choices=在models.py中设置一样,这将设置表单字段的选项(例如下拉菜单或单选按钮)。

{field_name} _max()

max=在models.py中设置的动态替代方法。例如:

{field_name} _min()

min在models.py中设置的动态替代方法。

{field_name} _error_message()

这是验证字段最灵活的方法。

例如,假设玩家必须进行购买,但此次购买不能超过玩家的预算。假设您的字段被调用purchase并且budget

一起验证多个字段

假设您的表单中有3个整数字段,其名称为 int1int2int3,并且提交的值必须总和为100.您可以使用以下error_message方法强制执行此操作:

动态确定表单域

如果您需要表单字段列表是动态的,而不是form_fields,您可以定义返回列表的方法get_form_fields(self)。 例如:

但是,如果这样做,您必须确保在模板中包含相同的{%formfield%}元素。 最简单的方法是使用{%formfields%}。

小部件

Django提供的表单输入小部件的完整列表就 在这里。

oTree另外提供:

  • RadioSelectHorizontalRadioSelect与水平布局相同,正如您将看到的Likert量表)
  • Slider
    • 要指定步长,请执行以下操作: Slider(attrs={'step': '0.01'})
    • 要禁用显示当前值,请执行以下操作: Slider(show_value=False)

自定义字段的外观

{%formfields%}和{%formfield%}易于使用,因为它们使用Bootstrap样式自动输出表单字段的所有必要部分(输入,标签和任何错误消息)。

但是,如果您想要更好地控制外观和布局,可以使用Django的手动场渲染。 不要{%formfield player.my_field%},而是{{form.my_field}},只获取输入,然后根据需要定位。

请记住还要包含{{form.my_field.errors}},这样如果表单中有错误,参与者将看到错误消息。

更多信息在这里。

示例:表格中的单选按钮和其他自定义布局

假设IntegerField您的模型中有一组:

并且您希望将它们呈现为一个类似的比例,其中每个选项都在一个单独的列中。

(首先,按照如何创建许多字段中的说明,尝试减少models.py中的代码重复。)

因为选项必须位于单独的表格单元格中,所以普通的RadioSelectHorizontal小部件在此处不起作用。

相反,您应该简单地循环遍历字段中的选项,如下所示:

如果您有许多具有相同选择数的字段,则可以将它们排列在表格中:

您还可以使用基于0的索引单独获取选项,例如 {{form.my_field.0}}为您提供了第一选择的单选按钮。 对于更精细的控制,如此处所述,您可以在字段选择上使用choice_label和tag属性。

高级:原始HTML小部件

如果和手动字段渲染 仍然不够灵活,您可以为表单输入编写原始HTML。但是,您将失去oTree自动处理的便捷功能。例如,如果表单有错误并且页面重新加载,则可能会清除用户的所有条目。{% formfield %}

要使用原始HTML,只需确保Page的每个字段form_fields 都有一个<input>具有匹配name属性的对应元素。

请记住,对于任何字段my_field,您应该包括,以便如果表单中有错误,参与者将看到错误消息。{{ form.my_field.errors }}

原始HTML示例:使用JavaScript的自定义用户界面

假设您不希望用户填写表单字段,而是与某种可视应用程序进行交互,例如点击图表或玩图形游戏。或者,您希望记录额外的数据,例如他们在页面的一部分上花了多长时间,他们点击了多少次等等。

您可以在任何所需的前端框架中构建这些接口。简单的可以使用jQuery完成; 更复杂的会使用像React或Polymer这样的东西。

然后,使用JavaScript记录相关数据点并将其存储在隐藏表单字段中。例如:

然后,您可以使用JavaScript设置该输入的值,方法是选择id的元素id_my_hidden_input,并设置其value属性。

提交页面时,隐藏输入的值将像任何其他表单字段一样记录在oTree中。

按钮

提交表单的按钮

如果您的页面只包含1个决定,则可以省略 ,而是让用户单击其中一个按钮转到下一页。{% next_button %}

例如,假设您的models.py有,而不是单选按钮,您希望将其显示为如下按钮:offer_accepted = models.BooleanField()

首先,像往常一样放入offer_accepted你的Page form_fields。然后将此代码放在模板中(这些btn类仅用于Bootstrap样式):

您可以将此技术用于任何类型的字段,而不仅仅是BooleanField

不提交表单的按钮

如果按钮除了提交表单之外有其他目的,请添加type="button"<button>

杂项和高级

具有动态矢量字段的表单

假设你想要一个带有n个字段向量相同的表单,除了一些数字索引,例如:

此外,假设n是可变的(范围从1到N)。

目前在oTree中,您只能在模型中定义固定数量的字段。因此,您应该在models.pyN fields(contribution_1...contribution_N...)中定义,然后get_form_fields如上所述使用动态返回包含这些字段的所需子集的列表。

例如,假设上面的变量n实际上是IntegerField玩家,它在游戏中的某个点动态设置。你可以get_form_fields 像这样使用:

带动态标签的表单字段

如果标签应包含变量,则可以在pages.py以下位置构造字符串:

然后在模板中,将标签设置为此变量:

如果您使用此技术,您可能还需要使用动态表单字段验证。

oTree学习教程(五)Forms相关推荐

  1. 【OpenCV图像处理入门学习教程五】基于背景差分法的视频目标运动侦测

    OpenCV图像处理入门学习教程系列,上一篇第四篇:基于LoG算子的图像边缘检测 运动目标检测 关于运动目标检测的方法总结,目前能够实现运动物体检测的方法主要有以下几种: 1)背景差分法:能完整快速地 ...

  2. oTree学习教程(七)Apps rounds

    应用 在oTree(和Django)中,app是一个包含Python和HTML代码的文件夹.当您创建oTree项目时,它会预先加载各种应用程序,例如 public_goods和dictator.会话基 ...

  3. oTree学习教程(一)概念性概述

    概念概述 Sessions 在oTree中,会话是指多个参与者参与一系列任务或游戏的事件.会话的一个例子是: "许多参与者将来到实验室并进行公共产品游戏,然后进行问卷调查.参与者获得的奖金为 ...

  4. oTree学习教程(六)Multiplayer games

    组 oTree的群组系统允许您将玩家分成小组并让玩家与同一组中的其他玩家互动.这通常用于多人游戏.(如果您只需要"治疗组"意义上的团体,其中玩家实际上并不相互交流,那么请参阅处理. ...

  5. oTree学习教程(二)Models

    Models models.py 是您定义应用程序数据模型的位置: Subsession Group Player Player是Group的一部分,这是Subsession的一部分.请参阅概念概述. ...

  6. oTree学习教程(四)Templates

    模板 您应用的templates/文件夹将包含显示给玩家的HTML模板. 模板语法 变量 您可以显示如下变量: 模板中提供以下变量: player:当前正在查看该页面的玩家 group:当前玩家所属的 ...

  7. oTree学习教程(八)Bots

    您可以编写模拟参与者播放应用程序的"机器人",以便您可以测试它是否正常运行. 很多oTree用户都跳过写机器人,因为他们认为这很复杂,或者因为他们太忙于为他们的应用程序编写代码.但 ...

  8. oTree学习教程(三)Pages

    Pages 玩家看到的每个页面都是由一个Page类定义的pages.py. 您pages.py必须有一个page_sequence 给出页面顺序的变量.例如: 如果您的游戏有多轮,则会重复此顺序.有关 ...

  9. jQuery学习教程五:jQuery 效果 - 淡入淡出, Fading 方法

    实例 jQuery fadeIn() 演示 jQuery fadeIn() 方法. <!DOCTYPE html> <html> <head> <script ...

最新文章

  1. 一手好牌打的稀烂,如今面临倒计时,网友哭求众筹活下去...
  2. 双眼融合训练一个月_视觉融合你知道多少
  3. QT的QCompleter类的使用
  4. Gradle project xxx refresh failed Error:Unable to tunnel through proxy. Proxy returns HTTP/...
  5. 工作中用到的安卓日志相关命令(logcat)
  6. 推荐系统遇上深度学习(六)--PNN模型理论和实践
  7. sqlyong导出sql没有数据_sqlyog怎么导入外部数据库-sqlyog导入数据库的方法 - 河东软件园...
  8. 生产者消费者模型、信号量、线程池以及单例模式的实现
  9. 割点(tarjan算法)
  10. oracle数据对应函数,Oracle函数取得姓名对应的拼音
  11. 清明时节雨纷纷路-清明节习俗、诗词欣赏
  12. 蚂蚁金服 花呗借呗 招聘公告
  13. Radware:防御现代鱼叉式网络钓鱼攻击的方法
  14. 二分图最大匹配与其应用
  15. redis之setnx、setex、setrange、mset
  16. 5G智慧灯杆系统在智慧街区的应用
  17. 网上订餐系统饿了么、百度、美团外卖,订餐网站外卖
  18. AutoHotKey 用打码的快捷键
  19. 【征文】Hadoop十周年特别策划——我与Hadoop不得不说的故事
  20. 开源授权协议GPL和LGPL的区别

热门文章

  1. 开启win7 Aero效果
  2. Linux终端无法启动图形界面应用,Could not connect to any X display.
  3. Python3教程: logging 模块用法
  4. MAX7221数码管驱动的多种探索
  5. 一个聊天场景的思考:初聊尬聊
  6. 学习《深入浅出python量化交易交易实战》第一章(笔记)
  7. Conrad Spirit Of Innovation Challenge康莱德创业挑战赛详细介绍
  8. Verilog 语言编写 OV7725摄像头初始化寄存器库与模块的初始化
  9. matlab如何新建mat文件,如何在Matlab中创建.mat文件?
  10. 2021年上半年信息系统项目管理师上午试题解析(三)