Обычно лучше проиндексировать твои объекты, предоставляющие интерфейс IClassA. Тогда в схеме второго интерфейса используем словарь собранный на основе индексов.
Если выбирать нужно только один объект из списка, тогда
interfaces.py ::
class IFoo(Interface):
selected = Choice(
title = u'Choice object',
required = False,
vocabulary = 'foo.vocabulary')
Теперь код словаря (могут быть другие варианты, я почти скопировал из своего текущего проекта). В данном случае в поле selected интерфейса IFoo хранятся именно индексы объектов (в этом есть плюсы и есть минусы, зависит от конкретного случая), ну а в форме отображается name.
vocabulary.py
from zope.component import getUtility
from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
from zope.security.proxy import removeSecurityProxy
from zope.app.intid.interfaces import IIntIds
from zope.app.catalog.interfaces import ICatalog
def fooVocabulary(context):
catalog = getUtility(ICatalog)
intids = getUtility(IIntIds)
result = catalog.apply({'class_a_index':{'any':None}},)
class_a_objects = [(id, removeSecurityProxy(intids.getObject(id)).name) for id in result]
terms = [SimpleTerm(value=id, token=id, title=name) for (id, name) in class_a_objects]
return SimpleVocabulary(terms)
Теперь зарегистрируем эту функцию как утилиту. configure.zcml ::
<utility
provides="zope.schema.interfaces.IVocabularyFactory"
component=".vocabulary.fooVocabulary"
name="foo.vocabulary"
/>
Остается тольк позаботиться о создании индекса ‘class_a_index’. Обычно это делается не ручным кликанием в ZMI, а в коде. Но можешь и вручную - добавь в сайт-менеджер каталог и в него индекс по любому полю для ICLassA, название индекса в данном случае, в примере - ‘class_a_index’. Про утилиту IIntIds только не забудь.
Однако если объекты ClassA однозначно находятся в каком-то одном контейнере - лучше чтоб утилита предоставляющая словарь читала не индексы, и values() этого контейнера, ИМХО.