Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 2, 2010 18:31:21

LightOfMooN
От:
Зарегистрирован: 2010-09-11
Сообщения: 127
Репутация: +  0  -
Профиль   Отправить e-mail  

BB IntIds

Зарегил утилиту 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 пустой. :(



Офлайн

#2 Окт. 2, 2010 20:04:26

Sleepwalker
От:
Зарегистрирован: 2008-07-18
Сообщения: 68
Репутация: +  0  -
Профиль   Отправить e-mail  

BB IntIds

Это лишнее:

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)
Тогда будеть производиться поиск утилиты относительно конкретного сайта.



Офлайн

#3 Окт. 2, 2010 20:12:21

LightOfMooN
От:
Зарегистрирован: 2010-09-11
Сообщения: 127
Репутация: +  0  -
Профиль   Отправить e-mail  

BB IntIds

Контекст не пишу, потому что утилита находится в корне (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 опустевает :(



Офлайн

#4 Окт. 2, 2010 20:23:51

Sleepwalker
От:
Зарегистрирован: 2008-07-18
Сообщения: 68
Репутация: +  0  -
Профиль   Отправить e-mail  

BB IntIds

Вот как сама утилита регистрирует обьект (и есле хочеш вручную делать это то что-то подобное нужно писать).
Это код хендлера который зарегистрировант на 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))



Офлайн

#5 Окт. 2, 2010 22:16:41

LightOfMooN
От:
Зарегистрирован: 2010-09-11
Сообщения: 127
Репутация: +  0  -
Профиль   Отправить e-mail  

BB IntIds

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 в корень?



Офлайн

#6 Окт. 2, 2010 23:20:01

LightOfMooN
От:
Зарегистрирован: 2010-09-11
Сообщения: 127
Репутация: +  0  -
Профиль   Отправить e-mail  

BB IntIds

Переписал немного код добавления 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])
что несколько печально



Отредактировано (Окт. 2, 2010 23:39:05)

Офлайн

#7 Окт. 3, 2010 12:16:58

LightOfMooN
От:
Зарегистрирован: 2010-09-11
Сообщения: 127
Репутация: +  0  -
Профиль   Отправить e-mail  

BB IntIds

Вопрос по предыдущему посту:
Как сделать чтобы оно работало автоматически?
Может, каких-то 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')



Отредактировано (Окт. 3, 2010 14:05:14)

Офлайн

#8 Окт. 3, 2010 15:32:51

LightOfMooN
От:
Зарегистрирован: 2010-09-11
Сообщения: 127
Репутация: +  0  -
Профиль   Отправить e-mail  

BB IntIds

Проблема решена, спасибо 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'уже установлено'
Всё работает, объекты регистрируются автоматически :)



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version