Web2py: SQLFORM.grid: создание двух уникальных столбцов

Вот мое определение базы данных:

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

Пожалуйста, помогите мне в этом.


person May    schedule 30.03.2015    source источник


Ответы (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))

Итак, вместо того, чтобы сделать поле недоступным для записи (и, следовательно, исключить его из формы) и установить значение по умолчанию, вышеприведенное предварительно заполняет значение в виджете и устанавливает виджет «только для чтения» (обратите внимание, с этим методом, злоумышленник может манипулировать значением, отправленным с формой, поэтому, если вас беспокоит такая возможность, вы можете добавить дополнительный валидатор, чтобы подтвердить, что отправленное значение соответствует значению в сеансе).

person Anthony    schedule 30.03.2015