0

这是我的数据库定义:

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.')

请帮助我。

4

1 回答 1

1

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

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

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

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))

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

于 2015-03-30T15:38:49.933 回答