web2py предотвращает дубликаты в таблице «многие ко многим»

#duplicates #many-to-many #web2py #data-access-layer

#дубликаты #многие ко многим #web2py #уровень доступа к данным

Вопрос:

У меня есть таблица для управления отношениями «многие ко многим» (работники и навыки) Работники могут иметь несколько навыков, и один навык может быть назначен нескольким работникам

Каков наилучший способ предотвратить дублирование записей, чтобы один навык не присваивался одному и тому же работнику дважды?

Спасибо

Ответ №1:

Если у вас есть что-то вроде:

 db.define_table('worker_skill',
    Field('worker', 'reference worker'),
    Field('skill', 'reference skill'))
  

Чтобы предотвратить дублирование при отправке формы, вы можете добавить средство проверки в одно из полей, например:

 db.worker_skill.skill.requires = IS_NOT_IN_DB(
    db(db.worker_skill.worker == request.vars.worker), 'worker_skill.skill'
)
  

Вышеизложенное гарантирует, что значение, вставляемое в «навык», не существует среди набора записей, где значение, вставляемое в «worker», соответствует полю «worker».

Другим вариантом проверки формы является использование onvalidation обратного вызова, как описано в главе «Формы» книги.

Вы также можете установить уникальное ограничение для пары столбцов непосредственно в базе данных (web2py не обрабатывает это, поэтому вам придется делать это с помощью внешнего инструмента). Это не поможет с проверкой формы, поскольку нарушение ограничения просто приведет к тому, что драйвер базы данных выдаст исключение (вместо того, чтобы предоставить конечному пользователю понятное сообщение об ошибке), но это будет полезно, если вы делаете вставки с помощью средств, отличных от формы web2py.

Комментарии:

1. После добавления валидатора в поле я теряю выпадающее меню, поскольку я использую два валидатора db.workers_skills.ws_skill.requires = [IS_NOT_IN_DB(db(db.workers_skills.ws_worker == request.vars.ws_worker), ‘workers_skills.ws_skill’), IS_IN_DB(db(db.skills.sk_organisation == org), db.skills.id , ‘%(sk_name)s’, ноль=T(‘Выбрать навык’)) ]

2. Это описано в книге — IS_IN_DB принимает _and аргумент — вы можете передать другой валидатор или список валидаторов, используя этот аргумент.