Улучшенный аналог ondelete=restrict для полей many2many
По умолчанию у полей с типом many2many нет параметра ondelete, как у полей с типом many2one, который отвечает за то, что делать с элементом, который ссылается на другой элемент, если этот другой элемент удаляют.
У опции ondelete есть в таком случае два варианта:
cascade — удалять элемент при удалении родителя (не знаю как правильно назвать тот элемент, НА который ссылаются)
restrict — запрет удаления родительского элемента
Бывают случаи, когда для полей many2many тоже было бы неплохо использовать аналог опции ondelete=restrict. У меня как раз такой случай. Есть две модели — product.attribute и product.attribute.group, между которыми связь many2many.
Я переопределил метод unlink, внутри которого проверяю наличие связей у удаляемой записи. Ниже пример для проверки связей при попытке удаления product.attribute:
Аналогичный код написан и для проверки при попытке удаления product.attribute.group. Если находим ссылки на удаляемую запись, тогда формируем строку с перечислением записей, которые ссылаются на текущую, и выводим пользователю сообщение о том, что сначала нужно удалить эти ссылки. Таким образом пользователь сразу узнает, что конкретно мешает удалению текущей записи (кстати хорошо бы было сделать такое же сообщение и при ondelete=restrict, а то там просто выводится ошибка, а что конкретно нужно сделать чтобы все-таки удалить запись, не написано).
Вы можете заметить что тексты сообщения обрамлены в функцию _(), это для того чтобы строки были переводимыми. Чтобы эту функцию использовать, нужно подключить ее такой строкой:
Вопросы и комментарии приветствуются.
Оригинал статьи: http://dskarataev.ru/2012/05/uluchshennyj-analog-ondeleterestrict-dlya-polej-many2many/
У опции ondelete есть в таком случае два варианта:
cascade — удалять элемент при удалении родителя (не знаю как правильно назвать тот элемент, НА который ссылаются)
restrict — запрет удаления родительского элемента
Бывают случаи, когда для полей many2many тоже было бы неплохо использовать аналог опции ondelete=restrict. У меня как раз такой случай. Есть две модели — product.attribute и product.attribute.group, между которыми связь many2many.
Я переопределил метод unlink, внутри которого проверяю наличие связей у удаляемой записи. Ниже пример для проверки связей при попытке удаления product.attribute:
def unlink(self, cr, uid, ids, context=None):
if context is None:
context = {}
for attribute in self.browse(cr, uid, ids):
attribute_group = self.pool.get('product.attribute.group')
attribute_group_ids = attribute_group.search(cr, uid, [('attribute_ids', 'in', attribute.id),])
if attribute_group_ids:
attribute_group_names = []
for attribute_group_element in attribute_group.browse(cr, uid, attribute_group_ids):
attribute_group_names.append(attribute_group_element.name)
attribute_group_names_str = ', '.join(attribute_group_names)
raise osv.except_osv(_('Some attribute groups have references to the attribute ') + attribute.name + '!',
_('First remove these references: ') + attribute_group_names_str)
return super(product_attribute_group, self).unlink(cr, uid, ids)
Аналогичный код написан и для проверки при попытке удаления product.attribute.group. Если находим ссылки на удаляемую запись, тогда формируем строку с перечислением записей, которые ссылаются на текущую, и выводим пользователю сообщение о том, что сначала нужно удалить эти ссылки. Таким образом пользователь сразу узнает, что конкретно мешает удалению текущей записи (кстати хорошо бы было сделать такое же сообщение и при ondelete=restrict, а то там просто выводится ошибка, а что конкретно нужно сделать чтобы все-таки удалить запись, не написано).
Вы можете заметить что тексты сообщения обрамлены в функцию _(), это для того чтобы строки были переводимыми. Чтобы эту функцию использовать, нужно подключить ее такой строкой:
from tools.translate import _
Вопросы и комментарии приветствуются.
Оригинал статьи: http://dskarataev.ru/2012/05/uluchshennyj-analog-ondeleterestrict-dlya-polej-many2many/
0 комментариев