这是我的数据库定义:
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.')
请帮助我。
答案 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))
因此,不是使字段不可写(因此将其从表单中排除)并设置默认值,而是上面预先填充窗口小部件中的值并将窗口小部件设置为“只读”(注意,使用这种方法,攻击者可以操纵随表单提交的值,所以如果您担心这种可能性,可以添加一个额外的验证器来确认提交的值与会话中的值匹配。)