[Zope-dev] SVN: z3c.form/trunk/ ``GroupForm`` and ``Group`` now use ``getContent`` method when instantiating group classes instead of directly accessing ``self.context``, as this is the usual way to access the context of the form and allows nested groups to have a different context than the main form.

Laurent Mignon laurent.mignon at softwareag.com
Tue Jan 19 03:44:34 EST 2010


Hi,

I doesn't understand the motivation behind this change and I've the 
feeling that it'll break some existing code....

May be am I wrong but  ``getContent`` method is used to provides values 
to widgets and actions as described into the interface:  '''Return the 
content to be displayed and/or edited.''' Why do you want to give the 
content to the subform. Providing the wright content according to its 
definition is under the subform responsability.

If not overrided, it's true that ``getContent`` return by default the 
context. But for me the fact that you give the result of a call to 
getContent as context for groupForm will break the following code:

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):
         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'}

person = Person(firstname='fName', address=Address(street='street'))
request = testing.TestRequest()

edit = PersonEditForm(person, request)


Before the changes the previous 'not tested' code worked as expected. 
Since you give the result of getContent when instantiating the SubForms, 
This code is now broken and I've to modify the getContent method on each 
subfoms to take the context on the parentForm pointer.

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):
         return {
            'owner': self.parentForm.context.firstname,
            'street': self.parentform.context.address.street}


As I've said, may be am I wrong but I've the feeling that using the 
``getContent`` as context for a subform introduce a mismatch between the 
2 concepts behind ``context`` and ``getContent`` and can break existing 
code.
The same result can be achieved, by explicitly instantiating the 
subforms into the parentForm constructor.

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))

Regards,

sagblmi




Michael Howitz wrote:
> Log message for revision 108077:
>   ``GroupForm`` and ``Group`` now use ``getContent`` method when instantiating group classes instead of directly accessing ``self.context``, as this is the usual way to access the context of the form and allows nested groups to have a different context than the main form.
>   
>   
> 
> Changed:
>   U   z3c.form/trunk/CHANGES.txt
>   U   z3c.form/trunk/src/z3c/form/group.py
> 
> -=-
> Modified: z3c.form/trunk/CHANGES.txt
> ===================================================================
> --- z3c.form/trunk/CHANGES.txt	2010-01-12 16:55:11 UTC (rev 108076)
> +++ z3c.form/trunk/CHANGES.txt	2010-01-12 17:33:51 UTC (rev 108077)
> @@ -5,7 +5,9 @@
>  2.3.1 (unreleased)
>  ------------------
>  
> -- Nothing changed yet.
> +- ``GroupForm`` and ``Group`` now use ``getContent`` method when
> +  instantiating group classes instead of directly accessing
> +  ``self.context``.
>  
>  
>  2.3.0 (2009-12-28)
> 
> Modified: z3c.form/trunk/src/z3c/form/group.py
> ===================================================================
> --- z3c.form/trunk/src/z3c/form/group.py	2010-01-12 16:55:11 UTC (rev 108076)
> +++ z3c.form/trunk/src/z3c/form/group.py	2010-01-12 17:33:51 UTC (rev 108077)
> @@ -52,7 +52,7 @@
>              if interfaces.IGroup.providedBy(groupClass):
>                  group = groupClass
>              else:
> -                group = groupClass(self.context, self.request, self)
> +                group = groupClass(self.getContent(), self.request, self)
>              group.update()
>              groups.append(group)
>          self.groups = tuple(groups)
> @@ -130,7 +130,7 @@
>              if interfaces.IGroup.providedBy(groupClass):
>                  group = groupClass
>              else:
> -                group = groupClass(self.context, self.request, self)
> +                group = groupClass(self.getContent(), self.request, self)
>              group.update()
>              groups.append(group)
>          self.groups = tuple(groups)



More information about the Zope-Dev mailing list