|
Firstly, thank you very much for your quick responses to my last query -
they put me on the right track. Now, I have another question... I have a class that needs to get values from another entry when it is created or edited. So, when creating a Person, the list of values that I can choose from for the type of Person are values that are editable on another entry. It LOOKS like I should be able to use a dynamically calculated SimpleVocabulary, but I can't get it to work - I think I need to use self.context on the interface definition of the schema field, but self is not defined. Alternatively, can I do it in setupWidgets before rendering? (Can't see enough information about setupWidgets to answer the question). Any help would be appreciated. Kathy _______________________________________________ Grok-dev mailing list [hidden email] https://mail.zope.org/mailman/listinfo/grok-dev |
|
This is what I do. I have a field defined in an interface:
gallery_id = schema.Choice(title=u"Gallery", vocabulary=u"Published NewProductGalleries") The vocabulary looks like this (it is a bit dirty, but it might help you in the right direction): import grok from zope import schema from zope.schema.vocabulary import SimpleVocabulary from boardsportsource import interfaces from boardsportsource import workflow from hurry import query class NewProductGalleriesSource(grok.GlobalUtility): grok.implements(schema.interfaces.IVocabularyFactory) grok.name('Published NewProductGalleries') def __call__(self, context): terms = self.get_published_galleries(context) return SimpleVocabulary(terms) def get_published_galleries(self, context): hasItem = [] if hasattr(context, 'gallery_id') and context.gallery_id is not None: # I allways need to have the current value in my vocabulary # or choice widgets won't render. hasItem.append(context.gallery_id) # I use hurry.query to find the objects I want to use in # my vocabulary. theQuery = query.Eq(('workflow_catalog', 'workflow_state'), workflow.PUBLISHED) theQuery = theQuery & query.Eq(('workflow_catalog', 'object_type'), 'new_product_gallery') dictResult = query.query.Query().searchResults(theQuery) theList = [] for item in dictResult: theObj = interfaces.INewProductGallery(item) theList.append(SimpleVocabulary.createTerm(theObj.__name__, theObj.__name__, '%s (%s)' % (theObj.title, 'default'))) if theObj.__name__ in hasItem: hasItem.remove(theObj.__name__) for key in hasItem: # If the current value wasn't found in the search I add it here # with an appropriate message. if grok.getSite()['default'].has_key(key): theObj = interfaces.IImageOfTheDayGallery(grok.getSite()['default'][key]) theList.append(SimpleVocabulary.createTerm(key, key, '%s (not published!)' % theObj.title)) else: theList.append(SimpleVocabulary.createTerm(key, key, '%s has been removed!' % key)) return theList Mvh Sebastian 26 nov 2009 kl. 11.00 skrev Kathy Manwaring: > Firstly, thank you very much for your quick responses to my last > query - > they put me on the right track. Now, I have another question... > > I have a class that needs to get values from another entry when it is > created or edited. So, when creating a Person, the list of values > that I > can choose from for the type of Person are values that are editable on > another entry. > > It LOOKS like I should be able to use a dynamically calculated > SimpleVocabulary, but I can't get it to work - I think I need to use > self.context on the interface definition of the schema field, but > self is > not defined. > > Alternatively, can I do it in setupWidgets before rendering? (Can't > see > enough information about setupWidgets to answer the question). > > Any help would be appreciated. > > Kathy > > _______________________________________________ > Grok-dev mailing list > [hidden email] > https://mail.zope.org/mailman/listinfo/grok-dev _______________________________________________ Grok-dev mailing list [hidden email] https://mail.zope.org/mailman/listinfo/grok-dev |
|
In reply to this post by Kathy Manwaring
Hi Sebastian,
Thank you so much for such a quick response and for including an actual code example! I am on a 3 day conference at the moment, but will try this out as soon as I can next week. Kathy Sebastian Ware wrote: > This is what I do. I have a field defined in an interface: > > gallery_id = schema.Choice(title=u"Gallery", vocabulary=u"Published NewProductGalleries") > > The vocabulary looks like this (it is a bit dirty, but it might help you in the right direction): > > > import grok > from zope import schema > from zope.schema.vocabulary import SimpleVocabulary > from boardsportsource import interfaces > from boardsportsource import workflow > from hurry import query > > class NewProductGalleriesSource(grok.GlobalUtility): > grok.implements(schema.interfaces.IVocabularyFactory) > grok.name('Published NewProductGalleries') > def __call__(self, context): > terms = self.get_published_galleries(context) > return SimpleVocabulary(terms) > > def get_published_galleries(self, context): > hasItem = [] > if hasattr(context, 'gallery_id') and context.gallery_id is not > # I allways need to have the current value in my vocabulary > # or choice widgets won't render. > hasItem.append(context.gallery_id) > > # I use hurry.query to find the objects I want to use in > # my vocabulary. > theQuery = query.Eq(('workflow_catalog', 'workflow_state'), workflow.PUBLISHED) > theQuery = theQuery & query.Eq(('workflow_catalog', 'object_type'), 'new_product_gallery') > dictResult = query.query.Query().searchResults(theQuery) > > theList = [] > for item in dictResult: > theObj = interfaces.INewProductGallery(item) > theList.append(SimpleVocabulary.createTerm(theObj.__name__, theObj.__name__, '%s (%s)' % (theObj.title, 'default'))) > if theObj.__name__ in hasItem: > hasItem.remove(theObj.__name__) > > for key in hasItem: > # If the current value wasn't found in the search I add it here > # with an appropriate message. > if grok.getSite()['default'].has_key(key): > theObj = interfaces.IImageOfTheDayGallery(grok.getSite()['default'][key]) > theList.append(SimpleVocabulary.createTerm(key, key, '%s (not published!)' % theObj.title)) > else: > theList.append(SimpleVocabulary.createTerm(key, key, '%s has been removed!' % key)) > return theList > > Mvh Sebastian > > > 26 nov 2009 kl. 11.00 skrev Kathy Manwaring: > >> Firstly, thank you very much for your quick responses to my last query - >> they put me on the right track. Now, I have another question... >> >> I have a class that needs to get values from another entry when it is >> created or edited. So, when creating a Person, the list of values that I >> can choose from for the type of Person are values that are editable on >> another entry. >> >> It LOOKS like I should be able to use a dynamically calculated >> SimpleVocabulary, but I can't get it to work - I think I need to use >> self.context on the interface definition of the schema field, but self is >> not defined. >> >> Alternatively, can I do it in setupWidgets before rendering? (Can't see >> enough information about setupWidgets to answer the question). >> >> Any help would be appreciated. >> >> Kathy >> >> _______________________________________________ >> Grok-dev mailing list >> [hidden email] >> https://mail.zope.org/mailman/listinfo/grok-dev _______________________________________________ Grok-dev mailing list [hidden email] https://mail.zope.org/mailman/listinfo/grok-dev |
|
Hi Group,
I'm using grok 1.2.1, and I have a problem calling a vocab in an addform: My vocabulary is as follows: class AccountMasterVocabularies(grok.GlobalUtility): grok.implements(schema.interfaces.IVocabularyFactory) grok.name('accnt') def __call__(self, context): return(schema.vocabulary.SimpleVocabulary([ schema.vocabulary.SimpleTerm('01', 'term 1', u'Really'), schema.vocabulary.SimpleTerm('02', 'term 2', u'Truly') ])) (So I would expect the vocab to be registered as 'accnt', no?) Then I have an Schema/Model as follows: class IGLLine(interface.Interface): """A Line""" account = schema.Choice(title=u"Account", vocabulary='accnt') class GLLine(grok.Model): """The implementation of the GLLine""" grok.context(GLLineContainer) grok.implements(IGLLine) account = None However, I get a VocabularyRegistryError because the vocabulary is unknown (see below). What am I missing???? Thanks in advance, Adam File '/Users/adamsummers1/.buildout/eggs/grok-1.2.1-py2.6.egg/grok/publication.py', line 90 in callObject return super(ZopePublicationSansProxy, self).callObject(request, ob) File '/Users/adamsummers1/.buildout/eggs/zope.app.publication-3.12.0-py2.6.egg/zope/app/publication/zopepublication.py', line 207 in callObject return mapply(ob, request.getPositionalArguments(), request) <groktwotwo.app.GLLineAddForm object at 0x303d610> File '/Users/adamsummers1/.buildout/eggs/zope.publisher-3.12.4-py2.6.egg/zope/publisher/publish.py', line 107 in mapply return debug_call(obj, args) File '/Users/adamsummers1/.buildout/eggs/zope.publisher-3.12.4-py2.6.egg/zope/publisher/publish.py', line 113 in debug_call return obj(*args) File '/Users/adamsummers1/.buildout/eggs/grokcore.formlib-1.6-py2.6.egg/grokcore/formlib/components.py', line 90 in __call__ self.update_form() File '/Users/adamsummers1/.buildout/eggs/grokcore.formlib-1.6-py2.6.egg/grokcore/formlib/components.py', line 62 in update_form super(GrokForm, self).update() File '/Users/adamsummers1/.buildout/eggs/zope.formlib-4.0.5-py2.6.egg/zope/formlib/form.py', line 758 in update self.setUpWidgets() File '/Users/adamsummers1/.buildout/eggs/zope.formlib-4.0.5-py2.6.egg/zope/formlib/form.py', line 739 in setUpWidgets form=self, adapters=self.adapters, ignore_request=ignore_request) File '/Users/adamsummers1/.buildout/eggs/zope.formlib-4.0.5-py2.6.egg/zope/formlib/form.py', line 266 in setUpWidgets field = field.bind(context) File '/Users/adamsummers1/.buildout/eggs/zope.schema-3.7.0-py2.6.egg/zope/schema/_field.py', line 291 in bind clone.vocabulary = vr.get(object, self.vocabularyName) File '/Users/adamsummers1/.buildout/eggs/zope.schema-3.7.0-py2.6.egg/zope/schema/vocabulary.py', line 166 in get raise VocabularyRegistryError(name) VocabularyRegistryError: unknown vocabulary: 'accnt' On 27 Nov 2009, at 4:48 PM, Kathy Manwaring wrote: > Hi Sebastian, > > Thank you so much for such a quick response and for including an actual > code example! > > I am on a 3 day conference at the moment, but will try this out as soon as > I can next week. > > Kathy > > Sebastian Ware wrote: >> This is what I do. I have a field defined in an interface: >> >> gallery_id = schema.Choice(title=u"Gallery", vocabulary=u"Published > NewProductGalleries") >> >> The vocabulary looks like this (it is a bit dirty, but it might help you > in the right direction): >> _______________________________________________ Grok-dev mailing list [hidden email] https://mail.zope.org/mailman/listinfo/grok-dev |
|
Hi all,
Just for the benifit of someone else who gets lost, here is the answer: Sources are the way to go. from zc.sourcefactory.basic import BasicSourceFactory class AccountMasterSource(BasicSourceFactory): def getValues(self): return grok.getSite()['AccountMaster'].values() #Dynamically generated. def getTitle(self, value): return value.name .... class IGLLine(interface.Interface): """A GL Line""" account = schema.Choice(title=u"Account", source=AccountMasterSource()) Also see: I have a question, -- why is this page marked as outdated? Regards, Adam On 8 Jan 2011, at 10:23 AM, Adam Summers wrote:
_______________________________________________ Grok-dev mailing list [hidden email] https://mail.zope.org/mailman/listinfo/grok-dev |
|
You don't need any specific extra packages :
from grokcore.component import provider from zope.schema.interfaces import IContextSourceBinder @provider(IContextSourceBinder) def some_source(context): return WHATEVER_YOU_NEED then, in your Choice definition : source=some_source and you're good to go 2011/1/9 Adam Summers <[hidden email]>: > Hi all, > Just for the benifit of someone else who gets lost, here is the answer: > Sources are the way to go. > from zc.sourcefactory.basic import BasicSourceFactory > > class AccountMasterSource(BasicSourceFactory): > def getValues(self): > return > grok.getSite()['AccountMaster'].values() #Dynamically generated. > > def getTitle(self, value): > return value.name > > .... > > > class IGLLine(interface.Interface): > """A GL Line""" > account = schema.Choice(title=u"Account", > source=AccountMasterSource()) > Also see: > http://grok.zope.org/documentation/how-to/using-sources-in-your-forms > I have a question, -- why is this page marked as outdated? > Regards, > Adam > > On 8 Jan 2011, at 10:23 AM, Adam Summers wrote: > > Hi Group, > > I'm using grok 1.2.1, and I have a problem calling a vocab in an addform: > > My vocabulary is as follows: > > class AccountMasterVocabularies(grok.GlobalUtility): > grok.implements(schema.interfaces.IVocabularyFactory) > grok.name('accnt') > > def __call__(self, context): > return(schema.vocabulary.SimpleVocabulary([ > schema.vocabulary.SimpleTerm('01', 'term 1', > u'Really'), > schema.vocabulary.SimpleTerm('02', 'term 2', > u'Truly') ])) > > (So I would expect the vocab to be registered as 'accnt', no?) > > Then I have an Schema/Model as follows: > > class IGLLine(interface.Interface): > """A Line""" > account = schema.Choice(title=u"Account", vocabulary='accnt') > > class GLLine(grok.Model): > """The implementation of the GLLine""" > grok.context(GLLineContainer) > grok.implements(IGLLine) > account = None > > However, I get a VocabularyRegistryError because the vocabulary is unknown > (see below). What am I missing???? > > Thanks in advance, > Adam > > > File > '/Users/adamsummers1/.buildout/eggs/grok-1.2.1-py2.6.egg/grok/publication.py', > line 90 in callObject > return super(ZopePublicationSansProxy, self).callObject(request, ob) > File > '/Users/adamsummers1/.buildout/eggs/zope.app.publication-3.12.0-py2.6.egg/zope/app/publication/zopepublication.py', > line 207 in callObject > return mapply(ob, request.getPositionalArguments(), request) > <groktwotwo.app.GLLineAddForm object at 0x303d610> > File > '/Users/adamsummers1/.buildout/eggs/zope.publisher-3.12.4-py2.6.egg/zope/publisher/publish.py', > line 107 in mapply > return debug_call(obj, args) > File > '/Users/adamsummers1/.buildout/eggs/zope.publisher-3.12.4-py2.6.egg/zope/publisher/publish.py', > line 113 in debug_call > return obj(*args) > File > '/Users/adamsummers1/.buildout/eggs/grokcore.formlib-1.6-py2.6.egg/grokcore/formlib/components.py', > line 90 in __call__ > self.update_form() > File > '/Users/adamsummers1/.buildout/eggs/grokcore.formlib-1.6-py2.6.egg/grokcore/formlib/components.py', > line 62 in update_form > super(GrokForm, self).update() > File > '/Users/adamsummers1/.buildout/eggs/zope.formlib-4.0.5-py2.6.egg/zope/formlib/form.py', > line 758 in update > self.setUpWidgets() > File > '/Users/adamsummers1/.buildout/eggs/zope.formlib-4.0.5-py2.6.egg/zope/formlib/form.py', > line 739 in setUpWidgets > form=self, adapters=self.adapters, ignore_request=ignore_request) > File > '/Users/adamsummers1/.buildout/eggs/zope.formlib-4.0.5-py2.6.egg/zope/formlib/form.py', > line 266 in setUpWidgets > field = field.bind(context) > File > '/Users/adamsummers1/.buildout/eggs/zope.schema-3.7.0-py2.6.egg/zope/schema/_field.py', > line 291 in bind > clone.vocabulary = vr.get(object, self.vocabularyName) > File > '/Users/adamsummers1/.buildout/eggs/zope.schema-3.7.0-py2.6.egg/zope/schema/vocabulary.py', > line 166 in get > raise VocabularyRegistryError(name) > VocabularyRegistryError: unknown vocabulary: 'accnt' > > On 27 Nov 2009, at 4:48 PM, Kathy Manwaring wrote: > > Hi Sebastian, > > Thank you so much for such a quick response and for including an actual > > code example! > > I am on a 3 day conference at the moment, but will try this out as soon as > > I can next week. > > Kathy > > Sebastian Ware wrote: > > This is what I do. I have a field defined in an interface: > > gallery_id = schema.Choice(title=u"Gallery", vocabulary=u"Published > > NewProductGalleries") > > The vocabulary looks like this (it is a bit dirty, but it might help you > > in the right direction): > > > _______________________________________________ > Grok-dev mailing list > [hidden email] > https://mail.zope.org/mailman/listinfo/grok-dev > > > _______________________________________________ > Grok-dev mailing list > [hidden email] > https://mail.zope.org/mailman/listinfo/grok-dev > > Grok-dev mailing list [hidden email] https://mail.zope.org/mailman/listinfo/grok-dev |
|
Hi there,
I have a source which looks like this: @provider(schema.interfaces.IContextSourceBinder) def AccountMasterSource(context): return(schema.vocabulary.SimpleVocabulary([schema.vocabulary.SimpleTerm(item.__name__, item.name) for item in grok.getSite()['AccountMaster'].values()])) Which works beautifully here when I have code in an interface as thus: class IGLLine(interface.Interface): """A GL Line""" entryDate = schema.Date(title=u"Date", default=date.today()) account = schema.Choice(title=u"Account", source=AccountMasterSource) ... but will not work in the following interface .... class IGLTransactionLine(interface.Interface): """This is the subline""" account = schema.Choice(title=u"Account", source=AccountMasterSource) drcr = schema.Choice(title=u"Debit/Credit", values=['DR', 'CR'], default='DR') class IGLTransaction(interface.Interface): entryDate = schema.Date(title=u"Date", default=date.today()) transactions = schema.List(title=u"Transactions", value_type=schema.Object(title=u'Transactions', schema = IGLTransactionLine), default=[], required=False) When I add a GLTransaction, I get the following error (see traceback in attachment). File '/Users/adamsummers1/.buildout/eggs/zope.schema-3.7.0-py2.6.egg/zope/schema/_field.py', line 481 in _validate_fields attribute.validate(getattr(value, name)) File '/Users/adamsummers1/.buildout/eggs/zope.schema-3.7.0-py2.6.egg/zope/schema/_bootstrapfields.py', line 147 in validate self._validate(value) File '/Users/adamsummers1/.buildout/eggs/zope.schema-3.7.0-py2.6.egg/zope/schema/_field.py', line 325 in _validate if value not in vocabulary: TypeError: argument of type 'function' is not iterable ... and its because of the source specified in the schema.Choice. Is my interface defined the correct way? I've also included a simplified extract of the code... Once again, thanks for the help! Adam _______________________________________________ Grok-dev mailing list [hidden email] https://mail.zope.org/mailman/listinfo/grok-dev |
|
Hi List,
I think I've stumbled across a bug when using schemas to validate input. Please see the app.py attached. Please have a look at the following tests when using choices in the app.py: 1) a Simple Schema.Choice with static results -- all OK 2) a Simple Schema.Choice using sources -- all OK 3) a Schema.List which contains objects of the type used in in (1) -- all OK 4) a Schema.List which contains objects of the type used in (2) -- this cannot work and you get the following error: >> if value not in vocabulary:TypeError: argument of type 'function' is not iterable (full traceback is also attached) The interesting thing to note is that in the 4th test, the object 'value' has an attribute vocabulary which is set to the source function, whereas I have noted when using pdb this is usually a list of simpleterms (ie, the result of the called function). Please let me know if I'm using the source incorrectly, I've had a frustrating two days trying to get through this. Any help is much appreciated. Regards, Adam _______________________________________________ Grok-dev mailing list [hidden email] https://mail.zope.org/mailman/listinfo/grok-dev |
| Powered by Nabble | Edit this page |
