Michael Howitz wrote:
> The motivation is the following:
> 
> self.getContent() seems to be the pattern to access the context of a form. I 
> used grep: there is no place where self.context is used directly besides in 
> group.py. So it seems to be an error in the code not to use the common 
> pattern.
> But after reading the doctests of z3c.form I'm no longer sure whether this is 
> correct.
> 
> My use case is the following:
> 
> I have a folder with contained items. In a form I display the schema of the 
> folder in the group form and the schemas of all contained items as groups. 
> Each group has a nested group displaying the meta data for the group's 
> content. As the context of the groups was the folder (group = 
> groupClass(self.context, self.request, self)) the meta data displayed was 
> wrong.
> 
But if your Groupform override getContent to provide an object 
implementing the expected interface, that's right

>> Class IAddress(Interface):
>>     street = zope.schema.TextLine(
>>              title='street')
>>
>> Class IPerson(Interface);
>>     firstname = zope.schema.TextLine(
>>              title='firstname')
>>
>>     address = zope.schema.Object(
>>              title='address',
>>              schema = IAddress)
>>
>>
>> class Address(object):
>>     implements(IAddress)
>>
>>     def __init__(self, **kw):
>>         for name, value in kw.items():
>>          setattr(self, name, value)
>>
>>
>> class Person(object):
>>     implements(IPerson)
>>
>>     def __init__(self, **kw):
>>         for name, value in kw.items():
>>          setattr(self, name, value)
>>
>> class AddressGroup(group.Group):
>>     label = 'Address'
>>     fields = field.Fields(zope.schema.TextLine(
>>             __name__ = 'owner',
>>             title='Owner',
>>             readOnly=True)
>>     fields += field.Fields(IAddress).select('street')
>>
>>     def getContext(self):
> 
> Should be "getContent", I think.
> 
>>         return {
>>            'owner': self.context.firstname,
>>            'street': self.context.address.street}
>>
>> class PersonGroup(group.Group):
>>     label = 'Person'
>>     fields += field.Fields(IPerson).select('firstname')
>>
>>
>> class PersonEditForm(group.GroupForm, form.EditForm):
>>      fields = field.Fields(zope.schema.TextLine(
>>            __name__="description',
>>            title='Description',
>>            readOnly=True)
>>      groups = (PersonGroup, AddressGroup)
>>
>>      def getContent(self):
>>          return {'description': 'Form used to edit a person and its 
>> Address'}
> 
> I had never seen this before but according to the doctests of z3c.form it is 
> a valid use case.

My understand of ``getContent`` is to provide a way to give values used 
by the widgets. By default, since the common use case is to edit / 
display values from the context, the implementation return the context.

If your form has to deal with fields defined in an interface not 
provided by the context, you have a lot of ways to provides the related 
values.
* The first one is to provide an adapter adapting the context to the 
interface defining the field
* The second one is to override the ``getContent`` implementation so 
it'll return an object implementing the right interface
* The thirds one is to override the ``getContent`` implementation so 
it'll return a dictionary where key = field.__name__ and value = the 
value expected by the field. (In fact a default adapter exist that adapt 
a dict to an interface)
* ...

Have a look to datamanager.txt....

>>
>> class MyEditForm(group.GroupForm, form.EditForm):
>>
>>     def __init__(self, context, request):
>>         super(MyEditForm, self).__init__(context, request)
>>         firstContext = {}
>>         secondContext = {}
>>      self.groups = (
>>          MyFirstGroup(firstcontext, request, self),
>>             MySecondGroup(secondContext, request, self))
> 
> I'm not sure whether this works. (I'll try it.) Whether it works it obsoletes 
> my changes.
> 

According to the z3c.form implemention, the right place to put your 
subform initialization is into the ``update`` method.

class MyEditForm(group.GroupForm, form.EditForm):

     def update(self):
        self.groups = (
            MyFirstGroup(self.context.obj1, request, self),
              MySecondGroup(self.context.obj2, request, self))
         super(MyEditForm,self).update()

Yours sincerely,

sagblmi


_______________________________________________
Zope-Dev maillist  -  Zope-Dev@zope.org
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )

Reply via email to