在Web2py中使用lambda作为模型默认值

在Web2py中使用lambda作为模型默认值,lambda,default,data-access-layer,web2py,Lambda,Default,Data Access Layer,Web2py,我尝试使用lambda根据中的值设置默认值 另一张桌子 这是我的模型: db.define_table('trip_instance', timestamp, sos_table, Field('trip_type_id', db.trip_type, label='Trip Type', widget=trip_select_widget, requires = IS_IN_DB(db, 'trip_type.id', '% (name)s'), r

我尝试使用lambda根据中的值设置默认值 另一张桌子

这是我的模型:

db.define_table('trip_instance', timestamp, sos_table, 
    Field('trip_type_id',  db.trip_type, label='Trip Type', 
       widget=trip_select_widget, requires = IS_IN_DB(db, 'trip_type.id', '% 
       (name)s'), represent=lambda id:db.trip_type(id)['name']), 
    Field('total_slots', 'integer', default=lambda r: 
       db.trip_type(r.trip_type_id)['total_slots']), 
在本地,这会导致一个错误,显示:

TypeError: <lambda>() takes exactly 1 argument (0 given) 
TypeError:()正好接受1个参数(给定0)
在我的服务器(Linode)上没有错误,但当我尝试创建 带有sqlform的新trip实例total slots字段为pre- 填充了以下内容:

<function <lambda> at 0x7f27684b7140> 

我的lambda看起来几乎和我的一样 在trip\u type\u id字段中表示,但我使用的是表
这场比赛的最后一场。这就是我做错的吗

如果您使用可调用(例如lambda)作为字段默认值,我认为它不能接受任何参数。默认值用于预填充表单字段,因此它们不应依赖于记录中的其他字段值

另一种方法是使用(尽管默认情况下它们不会出现在SQLFORMs中)。另一个选项是在表单处理阶段处理赋值,可能通过onvalidation函数——类似如下:

form.accepts(...,onvalidation=lambda form:form.vars.update(
    total_slots=form.vars.total_slots or
    db.trip_type(form.vars.trip_type_id)['total_slots']))
在上面的代码中,如果提交了total_slot的值,则保留该值——否则,将根据提交的trip_type_id的值从trip_type表中提取一个默认值

更新:

如注释中所述,如果在表单中包含total_slots字段,则如果在提交表单时该字段为空,则数据库中将存储一个空值,而不是计算值。为了避免此问题,您可以为表单指定一个onvalidation函数,用于检查form.vars.total_插槽是否为空,如果为空,则删除form.vars.total_插槽。在这种情况下,由于DB insert中不包括total_插槽,因此将调用compute函数来填充该值

如果要完全避免在表单处理阶段执行任何操作,另一个选项可能是为total_slots字段创建一个。验证程序的
\uuuuu init\uuuuuu
方法可以将request.vars作为参数,以便在提交表单时验证程序可以使用提交的记录值。当调用验证器时(即
\uuu call\uu
方法),它可以检查total\u slot的值是否为空,如果为空,它可以用通过字段的计算函数计算的值替换它。使用此设置,标准计算函数将处理直接DB插入,而验证器将通过表单处理插入


注意,使用validator方法,将根据request.vars中的值计算总_插槽的值,这些值是验证前提交的变量的值。在这种情况下,这应该不是问题,但更一般地说,如果任何字段验证器涉及转换,request.vars中的值将与最终插入DB记录的值不完全匹配。

谢谢您的回答。我尝试了一个计算字段,并将其显示在SQLForm中,但每当我在该表单字段中输入一个值并提交时,它总是被计算字段lambda覆盖,即使web2py book似乎说它不应该被覆盖。我甚至在模型中尝试了writeable=true。有什么办法让它发挥作用吗?由于其他限制,如果可能的话,我宁愿在模型级别而不是表单级别执行此操作。如果在表单中包含total_slot,则在提交表单时,应该忽略计算函数,即使total_slot字段为空。因此,如果表单字段保留为空,那么该字段在DB中应该是空的——它不应该被计算函数覆盖。