Найти - Пользователи
Полная версия: BB IntIds
Начало » Zope/Plone/Bluebream » BB IntIds
1
LightOfMooN
Зарегил утилиту intids, регистрирую объект. Вроде всё нормально.
    def createAndAdd(self, data):
shopcatalog = Shopcatalog()
shopcatalog.name = data['name']
self.context[shopcatalog.name] = shopcatalog
sm = getSiteManager()
ii = sm.queryUtility(IIntIds)
ii.register(shopcatalog)
self.request.response.redirect('.')
Перезапускаю сервак, и intids пустой. :(
Sleepwalker
Это лишнее:
sm = getSiteManager()
ii = sm.queryUtility(IIntIds)
ii.register(shopcatalog)
Утилита IntId сама регистрирует обьект (при условии что при добавлении обьекта идет нотификация ObjectAddedEvent).

Событие ObjectAddedEvent автоматически срабатывает когда вы добавляете обьект в контейнер (self.context = shopcatalog).

Так что правильнее писать без указанных выше строчек (возможно из-за этого и не сохраняет что идет два раза регистрация обьекта).

Еще возможные проблемы:

1. У вас может быть несколько утилит IntId
2. Shopcatalog не контейнер (проверте или наследуется от класса контейнера).

Еще, ii = sm.queryUtility(IIntIds) не совсем корректно опять же в случае нескольких утилит. Правлим хорошего тона есть указание контекста при поиске утилиты:

ii = sm.queryUtility(interface=IIntIds, context = self.context)
Тогда будеть производиться поиск утилиты относительно конкретного сайта.
LightOfMooN
Контекст не пишу, потому что утилита находится в корне (root).
IntIds - в единственном экземпляре.
Shopcatalog наследуется от BTreeContainer.

Вот код, которым создана IntIds:
            sm = getSiteManager()
if sm.queryUtility(IIntIds) is None:
intids = IntIds()
sm[u'intids'] = intids
sm.registerUtility(intids, IIntIds)
return 'done'
else: return 'already exists'
Утилита создана, проверял через shell.
Напрямую регистрировал объект
ii.register(shopcatalog)
Выводил list(ii), объект был добавлен
функции getObject() и getId() соответственно тоже работали.
transaction.commit(), рестарт серва, и ii опустевает :(
Sleepwalker
Вот как сама утилита регистрирует обьект (и есле хочеш вручную делать это то что-то подобное нужно писать).
Это код хендлера который зарегистрировант на IObjectAddedEvent:

@adapter(ILocation, IObjectAddedEvent)
def addIntIdSubscriber(ob, event):
"""A subscriber to ObjectAddedEvent

Registers the object added in all unique id utilities and fires
an event for the catalogs.
"""
utilities = tuple(getAllUtilitiesRegisteredFor(IIntIds))
if utilities: # assert that there are any utilites
key = IKeyReference(ob, None)
# Register only objects that adapt to key reference
if key is not None:
idmap = {}
for utility in utilities:
idmap[utility] = utility.register(key)
# Notify the catalogs that this object was added.
notify(IntIdAddedEvent(ob, event, idmap))
LightOfMooN
from zope.component import getSiteManager
from zope.site import LocalSiteManager
from zope.intid import IntIds, IIntIds
from zope.lifecycleevent import notify, ObjectAddedEvent
from zope.component.interfaces import IPossibleSite
from zope.interface import implements
from zope.site.folder import Folder
import transaction

obj = root[u'folder']
sm = obj.getSiteManager()
intids=IntIds()
sm[u'intids']=intids
sm.registerUtility(intids, IIntIds)
obj[u'f1']=Folder()
ii = sm.getUtility(IIntIds)
ii.register(obj[u'f1'])
transaction.commit()
Перезапускаю, проверяю - всё работает как надо. IntIds сохраняет значения.

Но это в локальном сайт менеджере.

А если сделать в корне, то что-то не работает.
Вопрос: что именно?

Вот так я добавлял IntIds в root:
            sm = getSiteManager()
if sm.queryUtility(IIntIds) is None:
intids = IntIds()
sm[u'intids'] = intids
sm.registerUtility(intids, IIntIds)
Но, похоже sm.queryUtility(IIntIds) не вернуло None, хотя IntIds добавлено не было.
Ибо попробовав добавить его через shell следующим кодом:
sm = getSiteManager()
intids = IntIds()
sm[u'intids'] = intids
я получил ошибку: ‘BaseGlobalComponents’ object does not support item assignment

Отсюда вопрос: как добавить IntIds в корень?
LightOfMooN
Переписал немного код добавления intids:
            sm = getSiteManager(self.context)
if sm.queryUtility(IIntIds, u'intids') is None:
intids = IntIds()
sm[u'intids'] = intids
sm.registerUtility(intids, IIntIds, u'intids')
self.request.form['result']=u'установлено'
else: self.request.form['result']=u'уже установлено'
Функция getSiteManager() работает аналогично getGlobalSiteManager() и возвращает ‘BaseGlobalComponents’. Что это, для меня пока загадка, ибо совсем новичок :). Но суть не в этом.
Если указать любой контекст, то вернётся LocalSiteManager от того же root.
В итоге, утилита работает. Значения сохраняются.
Вот только не добавляются автоматически. Приходится явно писать:
добавление какого-либо объекта (Object)
...
object = Object()
self.context[name] = object
sm = getSiteManager(self.context)
ii = sm.getUtility(IIntIds, u'intids')
ii.register(self.context[name])
что несколько печально
LightOfMooN
Вопрос по предыдущему посту:
Как сделать чтобы оно работало автоматически?
Может, каких-то zcml директив не хватает?

Ещё вопрос.
Проверяю через shell:
>>> sm=getSiteManager(root)
>>> ii = sm.getUtility(IIntIds)
>>> ii
<zope.intid.Intids object at 0x033184F0>
>>> ii = sm.getUtility(IItnIds, u'intids')
<zope.intid.Intids object at 0x0340A830>
Итого 2 объекта IntIds, хотя регистрировал только один.
Почему?
И правильно ли произведена регистрация?
            sm = getSiteManager()
if sm.queryUtility(IIntIds) is None:
intids = IntIds()
sm[u'intids'] = intids
sm.registerUtility(intids, IIntIds, u'intids')
Может, правильнее вот так?
            sm = getSiteManager()
if sm.queryUtility(IIntIds) is None:
intids = IntIds()
sm[u'intids'] = intids
sm.registerUtility(sm[u'intids'], IIntIds, u'intids')
LightOfMooN
Проблема решена, спасибо astoon :)

Добавил директиву включения intid в site.zcml
<include package="zope.intid" />
И переписал код добавления утилиты на следующий:
            sm = getSiteManager(self.context)
if u'intids' not in sm:
intids = IntIds()
notify(ObjectCreatedEvent(intids))
sm[u'intids'] = intids
sm.registerUtility(intids, IIntIds)
self.request.form['result']=u'установлено'
else: self.request.form['result']=u'уже установлено'
Всё работает, объекты регистрируются автоматически :)
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