Web2py:SQLFORM.grid:使2列唯一

时间:2015-03-30 10:45:48

标签: web2py web2py-modules

这是我的数据库定义:

db.define_table('emsAlertTokens',

Field('emsrelease','string',default=session.releasefield,writable=False,label=T('Release')),
            Field('emsmachine','string',default=session.machinefield,writable=False,label=T('Machine')),
            Field('emsstartdate','datetime',default=request.now,label=T('Start Date')),
            Field('emsenddate','datetime',IS_NOT_EMPTY(error_message='Please specify the End Date.'), label=T('End Date')),
            Field('errorgrepfile','upload',requires=IS_NOT_EMPTY(error_message='Please upload a valid error tokens file'),custom_store=ems_file, custom_retrieve=ems_retrieve, autodelete=True, uploadfield=True, uploadfs=None, label=T('Error Tokens')),
            Field('tokenname','string',requires=IS_NOT_EMPTY('What would you call your token file?'),label=T('Token File Name')))

您可以注意到emsmachine和emsrelease字段来自会话。我的要求是使这两个值的组合是唯一的。

我尝试使用下面的验证器,但它没有工作。

db.emsAlertTokens.emsrelease.requires = IS_NOT_IN_DB(db(db.emsAlertTokens.emsmachine == session.machinefield), 'emsAlertTokens.emsrelease', error_message='EMS token file already exist for this release.')

即便这样也行不通:

db.emsAlertTokens.emsrelease.requires = IS_NOT_IN_DB(db(db.emsAlertTokens.emsmachine == request.vars.emsmachine), 'emsAlertTokens.emsrelease', error_message='EMS token file already exist for this release.')

请帮助我。

1 个答案:

答案 0 :(得分:1)

验证器用于表单输入,并且因为这两个字段不可写(因此不是表单的一部分),验证器不会被应用(为不可写字段设置的默认值不会被验证)。

鉴于这些字段的默认值在某个先前点被添加到会话中,您应该在那时验证它们的联合唯一性。

另一种选择是在表单中包含预填充值的字段,但包含HTML“readonly”属性以防止用户更改它:

Field('emsrelease', 'string', label=T('Release'),
      widget=lambda f, v: SQLFORM.widgets.string.widget(f, session.releasefield,
                                                        _readonly=True),
      requires=IS_NOT_IN_DB(db(db.emsAlertTokens.emsmachine == session.machinefield),
                            'emsAlertTokens.emsrelease',
                            error_message='EMS token file already exist for this release.')),
Field('emsmachine', 'string', label=T('Release'),
      widget=lambda f, v: SQLFORM.widgets.string.widget(f, session.machinefield,
                                                        _readonly=True))

因此,不是使字段不可写(因此将其从表单中排除)并设置默认值,而是上面预先填充窗口小部件中的值并将窗口小部件设置为“只读”(注意,使用这种方法,攻击者可以操纵随表单提交的值,所以如果您担心这种可能性,可以添加一个额外的验证器来确认提交的值与会话中的值匹配。)