[Zope3-Users] Re: Adapters and getters and setters

Philipp von Weitershausen philipp at weitershausen.de
Tue Jul 25 04:16:41 EDT 2006


Darryl Cousins wrote:
> I only recently began using formlib and I have used a schema to describe
> the form, and provided an adapter to adapt the object to the schema.
> 
> It seems that formlib uses the adapter to access and set attributes on
> the object.

That's correct. That way, for example, you can have an edit form made
from the IZopeDublinCore interface for objects that don't provide this
interface directly. The edit form will instead operate on the adapter,
and therefore actually set the dublin core metadata the right way.

> To allow it to do that I need to provide getters and setters
> for the adapter to access the attributes on the object itself:

That doesn't make sense. Either your adapter implements the full range
of the form schema (in which case you might want to dispatch the
attribute assignment for certain form fields or not...) or it doesn't
(in which case you have a bug).

> Before using formlib I would usually have a getContext() method on the
> adapter to return the adapted object and manually get or set the
> attributes (in the update method for example). Doing the above means I
> don't need to.
> 
> Am I going about this the right way?

The getContext() thing is superfluous. The adaption is much more flexible.

Let's say you have a buddy schema:

  class IBuddy(zope.interface.Interface):
      first = TextLine(title=_("First name"))
      last = TextLine(title=_("Last name"))
      email = TextLine(title=_("Electronic mail address"))
      address = Text(title=_("Postal address"))
      postal_code = TextLine(title=_("Postal code"),
           constraint=re.compile("\d{5,5}(-\d{4,4})?$").match)

Now, the edit form for this could be different:

  class IBuddyForm(IBuddy):
      # also allow city to be entered, we deduce postal_code
      # from that
      city = TextLine(title=_("City"))

Now, buddies don't provide IBuddyForm, they only provide IBuddy. Hence
we need an adapter:

  class BuddyFormAdapter(object):
      adapts(IBuddy)
      implements(IBuddyForm)

      def __init__(self, context):
          self.context = context

      # account for everything in the IBuddy interface
      for field in IBuddy:
          locals()[field] = property(
              lambda self: getattr(self.context, field),
              lambda self, value: setattr(self.context, field, value)
              )

      # account for additional stuff in IBuddyForm
      def getCity(self):
          return getCityFromPostalCode(self.postal_code)
      def setCity(self):
          postal_code = getPostalCodeFromCity(city)
          self.postal_code = postal_code
      city = property(getCity, setCity)



More information about the Zope3-users mailing list