Найти - Пользователи
Полная версия: BB: Какие есть варианты реализации ссылки на объект?
Начало » Zope/Plone/Bluebream » BB: Какие есть варианты реализации ссылки на объект?
1
Cykooz
Требуется реализовать поле в объекте, которое будет хранить ссылку на другой объект в ZODB.
Самая первая пришедшая на ум реализация - хранить id объекта возвращаемый утилитой IIntIds.
После этого стал копать PyPi на предмет готовых компонентов. Нашёл только один более или менее подходящий пакет - gocept.reference. Все остальные найденые реализации довольно старые и не подходят для ZTK 1.1 без работы напильником.
К сожалению gocept.reference имеет, как мне кажется, небольшой недостаток - в качестве ссылки на объект он использует путь к нему от корня ZODB. Следовательно для получения объекта требуется выполнить полный траверс этого пути. По моему это не очень оптимальный вариант. Каких либо плюсов такого подхода я не вижу.

Может кому то уже приходилось делать, что то подобное? Как лучше это сделать?
Sleepwalker
Есть продукт z3c.relationfield. Чесно говоря не использовал его, но по описанию очень Вам подходит. Он завязан на IntIds.

Еще один вариан - использовать перзистентные WeakRef - http://docs.zope.org/zope3/Code/persistent/wref/WeakRef
Тогда и IntId не нужна. Этот вариант мне как-то больше по душе.
Cykooz
Sleepwalker
Есть продукт z3c.relationfield. Чесно говоря не использовал его, но по описанию очень Вам подходит. Он завязан на IntIds.
Да, он вероятно подошёл бы, но только он настолько старый что зависимости у него не очень хорошие (тот же IntIds берётся например из zope.app.intids).

Пока что начал использовать gocept.reference, там в принципе при желании можно переопределить класс Reference и использоувать свой метод для получения ключа к объекту.

А использование WeakRef, насколько я понял, может привести к проблемам, т.к. такая ссылка ссылается на конкретную версию объекта и при изменении объекта или его удалении будет по прежнему ссылаться на старую версию. Вот что по этому поводу написанно в доке к gocept.reference:
Weak references.
The reference might have become stale and leave the referencing object in an invalid state.
Sleepwalker
Ну да, поэтому и в примере с weakref что я кидал, база пакуется после удаления обьекта …
Cykooz
Подумав немного я понял, что вариант с IntIds не подходит, т.к. в моём случае важно не то на какой конкретно объект указывает ссылка, а на то где он находится в иерархии. В случае использования IntIds я могу переместить объект совершено в другое место и ссылка по прежнему будет указывать на него.
astoon
Наоборот weak reference решает проблемы, не?

Порассуждаю чуток.

В ZODB стопицот способов сделать отношения между объектами. Точнее - столько же, сколько есть в самом Python.

Соответственно, в кажом проекте используется много разных, наверняка, и в разных сочетаниях. Это нормально и это на каждом шагу. Например, самый распостраненный сопсобо - это протокол ILocation, и его персистемное воплощение IConainer / IContained.

Не забывайте, что если мы просто кладем объект в атрибуты несокльких другох объектов, то это не будет дублирование, это будет один объект. Т.е. ZODB это суть ваш пайтон код. Соответственно, это и есть самый правильный способ работать с ZODB, потому что надо получать преимущества от его использования в виде минимизации кода и сущностей в коде. А иначе зачем тогда вообзе использовать ZODB.

На месте же уже решать, класть сам объект, или его ID, или waek reference. Правда состоит в том, что на практике во всех случаях все равно нужно отслеживать удаление исходного объекта и предпринимать в связи с этим какие-то действия. Ну, на то есть события и подписчики.

Второй вопрос - чтобы виджеты изкоробки сразу работали по схеме. Например, если это Choice то задача сводится к тому, чтобы сделать корректный vocabulary, где title - это отображаемая строка, token и term - то, что сохраняем в (и берем из). Достоверно скажу лишь что это работает так, как и ожидается, испробовано много раз.
astoon
кроме intids / weak reference / reference лично я часто испорльзую __name__ объекта (или просто его числовой ключ, если он в IOBTree, атрибуте, а не в IContainer). В этих случаях известно, что объекты, на которые ссылаемся, лежат в определенном известном месте, так что не проблема взять их по __name__ или некоторому другому ключу.

А какое конкретно решение выбирать, тут уж каждый раз смотреть.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB