模型¶
一个oTree应用有三个数据模型:子会话,小组与玩家。
玩家是小组的一部分,小组是子会话的一部分。参考 概念总览.
假设你想要你的实验生成下面这样的数据:
name age is_student
John 30 False
Alice 22 True
Bob 35 False
...
下面的代码展示了如何定义上面的表结构:
class Player(BasePlayer):
name = models.StringField()
age = models.IntegerField()
is_student = models.BooleanField()
所以,一个 模型 实际上就是一张数据库表。一个 字段 就是表中的一列。
字段¶
字段类型¶
BooleanField
(表示 true/false 或者 yes/no 这样的值)CurrencyField
表示货币数量; 参考 货币.IntegerField
FloatField
(表示实数)StringField
(表示字符串)LongStringField
(表示长字符串; 它的表单控件是一个多行文本框)
初始/默认值¶
字段的初始值为 None
,除非你设置了 initial=
:
class Player(BasePlayer):
some_number = models.IntegerField(initial=0)
内置字段与方法¶
玩家,小组与子会话有一些预定义的字段。举例来说, Player
有 payoff
与 id_in_group
字段, in_all_rounds()
与 get_others_in_group()
方法.
这些内置的字段与方法列出如下。
玩家¶
id_in_group¶
自动被赋值为从1开始的正整数。在多人游戏中,表示哪位是玩家1,哪位是玩家2,诸如此类。
round_number¶
Gives the current round number.
常量¶
Constants
是推荐存放应用的参数或是玩家之间没有区别的常量的地方。
下面是内置的常量:
如果你不想让自己应用的真实名字被显示在URL中,那么可以定义一个字符串常量 name_in_url
并赋予你想显示的名字。
Constants can be numbers, strings, booleans, lists, etc.
But for more complex data types like dicts, lists of dicts, etc,
you should instead define it in a function. For example,
instead of defining a Constant called my_dict
, do this:
def my_dict(subsession):
return dict(a=[1,2], b=[3,4])
杂项¶
定义你自己的方法¶
除了本页列出的方法,你可以定义自己的方法。只需记住在 某处 调用它们!仅仅用 def
定义它们是没有任何作用的。
举例来说:
def set_payoffs(group):
print('in set_payoffs')
# etc ...
然后如下调用:
class MyWaitPage(WaitPage):
after_all_players_arrive = 'set_payoffs'
关于使用 random()¶
永远不要在方法外部生成随机值。举例来说,不要写下面这样的代码:
class Constants(BaseConstants):
p = random.randint(1, 10) # wrong
如果它随机变化,它就不算一个常量。
或者这样的代码:
class Player(BasePlayer):
p = models.FloatField(
# wrong
initial=random.randint(1, 10)
)
上述代码不会正常工作,因为随机值在服务器启动一个新进程时会改变。这可能在测试时工作正常,但最终会出现错误。相反的,你应该在方法内部生成随机值,如 实验组(Treatments) 中(尽量不要在 vars_for_template
中,因为这一方法在用户刷新页面时会重新执行)。
如果你想使用自己的随机种子,不要用 random.seed()
函数。而应当生成 random.Random
的实例,如在 这里 所描述的