[Checkins] SVN: grok/trunk/src/grok/ Big form refactoring:

Philipp von Weitershausen philikon at philikon.de
Thu Mar 15 17:49:03 EDT 2007


Log message for revision 73209:
  Big form refactoring:
  
  - Renamed grok.AddForm to grok.Form because there was no additional functionality
    in that base class that was specific to adding. Yes, it used formlib's AddForm,
    but none of the features it has to make adding objects easy for you were used
    (adding objects in Zope 3 is overly complicated anyway, thanks to IAdding).
    Everybody writing add forms was writing his/her own actions anyway, which is
    exactly what the point of a general grok.Form base class is.
  
  - Got rid of the "form in form" weirdness. It turns out that a very, very simple
    mix-in with a custom render() method makes it possible to mix formlib's base
    classes with grok.View. This makes the ViewGrokker simpler and exposes more of
    formlib directly in Grok forms.
  
  Apart from having to use grok.Form instead of grok.AddForm, existing applications
  shouldn't have to change.
  

Changed:
  U   grok/trunk/src/grok/__init__.py
  U   grok/trunk/src/grok/components.py
  U   grok/trunk/src/grok/formlib.py
  U   grok/trunk/src/grok/ftests/form/actions.py
  U   grok/trunk/src/grok/ftests/form/addform.py
  U   grok/trunk/src/grok/ftests/form/form.py
  U   grok/trunk/src/grok/interfaces.py
  U   grok/trunk/src/grok/meta.py
  U   grok/trunk/src/grok/templates/default_display_form.pt
  U   grok/trunk/src/grok/templates/default_edit_form.pt
  U   grok/trunk/src/grok/tests/form/customautoform.py
  U   grok/trunk/src/grok/tests/form/customform.py
  U   grok/trunk/src/grok/tests/form/fields.py
  U   grok/trunk/src/grok/tests/form/form.py
  D   grok/trunk/src/grok/tests/form/norender.py
  D   grok/trunk/src/grok/tests/form/norender2.py
  U   grok/trunk/src/grok/tests/form/schemaform.py
  U   grok/trunk/src/grok/tests/form/schemainherit.py

-=-
Modified: grok/trunk/src/grok/__init__.py
===================================================================
--- grok/trunk/src/grok/__init__.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/__init__.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -33,8 +33,7 @@
 from grok.components import Model, Adapter, MultiAdapter, View, XMLRPC
 from grok.components import PageTemplate, PageTemplateFile, Container, Traverser
 from grok.components import Site, GlobalUtility, LocalUtility, Annotation
-from grok.components import Application
-from grok.components import EditForm, DisplayForm, AddForm
+from grok.components import Application, Form, EditForm, DisplayForm
 from grok.directive import (context, name, template, templatedir, provides,
                             baseclass, global_utility, local_utility,
                             define_permission, require)

Modified: grok/trunk/src/grok/components.py
===================================================================
--- grok/trunk/src/grok/components.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/components.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -14,6 +14,7 @@
 """Grok components
 """
 
+import os
 import persistent
 import urllib
 
@@ -29,7 +30,6 @@
 from zope.publisher.publish import mapply
 from zope.pagetemplate import pagetemplate, pagetemplatefile
 from zope.formlib import form
-from zope.formlib.namedtemplate import INamedTemplate
 from zope.traversing.browser.interfaces import IAbsoluteURL
 from zope.traversing.browser.absoluteurl import AbsoluteURL
 from zope.traversing.browser.absoluteurl import _safe as SAFE_URL_CHARACTERS
@@ -161,16 +161,18 @@
             return
 
         template = getattr(self, 'template', None)
-        if not template:
-            return mapply(self.render, (), self.request)
+        if template is not None:
+            return self._render_template()
+        return mapply(self.render, (), self.request)
 
-        namespace = template.pt_getContext()
+    def _render_template(self):
+        namespace = self.template.pt_getContext()
         namespace['request'] = self.request
         namespace['view'] = self
         namespace['context'] = self.context
         # XXX need to check whether we really want to put None here if missing
         namespace['static'] = self.static
-        return template.pt_render(namespace)
+        return self.template.pt_render(namespace)
 
     def __getitem__(self, key):
         # XXX give nice error message if template is None
@@ -207,7 +209,6 @@
     def update(self):
         pass
 
-
 class GrokViewAbsoluteURL(AbsoluteURL):
 
     def _getContextName(self, context):
@@ -347,50 +348,43 @@
         # try to get the item from the container
         return self.context.get(name)
 
+default_form_template = PageTemplateFile(os.path.join(
+    'templates', 'default_edit_form.pt'))
+default_form_template.__grok_name__ = 'default_edit_form'
+default_display_template = PageTemplateFile(os.path.join(
+    'templates', 'default_display_form.pt'))
+default_display_template.__grok_name__ = 'default_display_form'
 
-class Form(View):
+class GrokForm(object):
+    """Mix-in to console zope.formlib's forms with grok.View and to
+    add some more useful methods."""
 
-    def __init__(self, context, request):
-        super(Form, self).__init__(context, request)
-        self.form = self.__real_form__(context, request)
-        # we need this pointer to the actual grok-level form in our
-        # custom Action
-        self.form.grok_form = self
+    def render(self):
+        # if the form has been updated, it will already have a result
+        if self.form_result is None:
+            if self.form_reset:
+                # we reset, in case data has changed in a way that
+                # causes the widgets to have different data
+                self.resetForm()
+                self.form_reset = False
+            self.form_result = self._render_template()
 
-    def __call__(self):
-        form = self.form
+        return self.form_result
 
-        form.update()
-
-        # this code is extracted and modified from form.render
-
-        # if the form has been updated, it may already have a result
-        if form.form_result is None:
-            # we reset, in case data has changed in a way that
-            # causes the widgets to have different data
-            if form.form_reset:
-                form.resetForm()
-                form.form_reset = False
-            # recalculate result
-            form.form_result = super(Form, self).__call__()
-
-        return form.form_result
-
     def apply_changes(self, obj, **data):
-        if form.applyChanges(obj, self.form.form_fields, data,
-                             getattr(self.form, 'adapters', {})):
+        if form.applyChanges(obj, self.form_fields, data, self.adapters):
             event.notify(ObjectModifiedEvent(obj))
             return True
         return False
 
-class EditForm(Form):
-    label = ''
-    status = ''
+class Form(GrokForm, form.FormBase, View):
 
-class AddForm(Form):
-    label = ''
-    status = ''
+    template = default_form_template
 
-class DisplayForm(Form):
-    label = ''
-    status = ''
+class EditForm(GrokForm, form.EditFormBase, View):
+
+    template = default_form_template
+
+class DisplayForm(GrokForm, form.DisplayFormBase, View):
+
+    template = default_display_template

Modified: grok/trunk/src/grok/formlib.py
===================================================================
--- grok/trunk/src/grok/formlib.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/formlib.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -1,10 +1,8 @@
-import os
 import types
 from zope import interface
 from zope.interface.interfaces import IInterface
 from zope.formlib import form
 from zope.schema.interfaces import IField
-from grok import components
 
 class action(form.action):
     """We override the action decorator we pass in our custom Action.
@@ -17,7 +15,7 @@
 class Action(form.Action):
     def success(self, data):
         if self.success_handler is not None:
-            return self.success_handler(self.form.grok_form, **data)
+            return self.success_handler(self.form, **data)
 
 def Fields(*args, **kw):
     fields = []
@@ -28,48 +26,7 @@
             del kw[key]
     fields.sort(key=lambda field: field.order)
     return form.Fields(*(args + tuple(fields)), **kw)
-    
-def setup_editform(factory, context):
-    """Construct the real edit form, taking needed information from factory.
-    """
-    actions_ = getattr(factory, 'actions', None)
-    if actions_ is None:
-        # set up the default edit action
-        actions_ = form.Actions(form.EditForm.handle_edit_action)
 
-    class RealEditForm(form.EditForm):
-        form_fields = get_form_fields(factory, context)
-        actions = actions_
-    # we do not use the class annotation infrastructure as we use
-    # this information during *runtime* not groktime.
-    factory.__real_form__ = RealEditForm
-
-def setup_displayform(factory, context):
-    """Construct the real display form, taking needed information from factory.
-    """
-    # get actions; by default no actions at all
-    actions_ = getattr(factory, 'actions', form.Actions())
-
-    class RealDisplayForm(form.DisplayForm):
-        form_fields = get_form_fields(factory, context)
-        actions = actions_
-    # we do not use the class annotation infrastructure as we use
-    # this information during *runtime* not groktime.
-    factory.__real_form__ = RealDisplayForm
-
-def setup_addform(factory, context):
-    """Construct the real add form, taking needed information from factory.
-    """
-    # get actions; by default no actions at all
-    actions_ = getattr(factory, 'actions', form.Actions())
-
-    class RealAddForm(form.AddForm):
-        form_fields = get_form_fields(factory, context)
-        actions = actions_
-    # we do not use the class annotation infrastructure as we use
-    # this information during *runtime* not groktime.
-    factory.__real_form__ = RealAddForm
-
 def get_context_schema_fields(context):
     """Get the schema fields for a context object.
     """
@@ -91,19 +48,6 @@
     fields.sort(key=lambda field: field.order)
     return fields
 
-def get_form_fields(factory, context):
-    """Get the form fields for a factory.
-
-    factory - the factory (view) we're determining the form fields for
-    context - the context that the factory creates a view for
-    """
-    # first check whether the factory already defines form fields,
-    # in which case we're done as those always override everything
-    fields = getattr(factory, 'form_fields', None)
-    if fields is not None:
-        return fields
-    return get_auto_fields(context)
-
 def get_auto_fields(context):
     """Get the form fields for context.
     """
@@ -144,16 +88,3 @@
         if seen_iface.extends(iface):
             return True
     return False
-
-def load_template(name):
-    filename = os.path.join(os.path.dirname(__file__), 'templates', name)
-    f = open(filename, 'r')
-    result = f.read()
-    f.close()
-    return result
-
-defaultEditTemplate = components.PageTemplate(load_template(
-    'default_edit_form.pt'))
-
-defaultDisplayTemplate = components.PageTemplate(load_template(
-    'default_display_form.pt'))

Modified: grok/trunk/src/grok/ftests/form/actions.py
===================================================================
--- grok/trunk/src/grok/ftests/form/actions.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/ftests/form/actions.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -1,8 +1,8 @@
 """
-Using the @grok.action decorator, different actions can be defined on a
-grok.EditForm. When @grok.action is used, the default behaviour (the 'Apply'
-action) is not available anymore, but it can triggered manually by calling
-self.apply_changes(object, data).
+Using the @grok.action decorator, different actions can be defined on
+a grok.Form. When @grok.action is used, the default behaviour (the
+'Apply' action) is not available anymore, but it can triggered
+manually by calling self.apply_changes(object, data).
 
   >>> import grok
   >>> from grok.ftests.form.actions import Mammoth
@@ -39,6 +39,12 @@
   ...Manfred the Second...
   ...Really big and hairy...
   ...
+
+  >>> browser.open("http://localhost/manfred/meet")
+  >>> browser.getControl(name="form.other").value = "Ellie"
+  >>> browser.getControl("Meet").click()
+  >>> print browser.contents
+  Manfred the Second meets Ellie
 """
 import grok
 from zope import schema
@@ -60,3 +66,12 @@
     def handle_hairy(self, **data):
         self.apply_changes(self.context, **data)
         self.context.size += " and hairy"
+
+class Meet(grok.Form):
+    form_fields = grok.Fields(
+        other = schema.TextLine(title=u'Mammoth to meet with')
+        )
+
+    @grok.action('Meet')
+    def meet(self, other):
+        return self.context.name + ' meets ' + other

Modified: grok/trunk/src/grok/ftests/form/addform.py
===================================================================
--- grok/trunk/src/grok/ftests/form/addform.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/ftests/form/addform.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -1,5 +1,5 @@
 """
-A grok.AddForm is a special grok.View that renders an add form.
+We can use grok.Form to render an add form for objects:
 
   >>> import grok
   >>> from grok.ftests.form.addform import Zoo, Mammoth
@@ -46,7 +46,7 @@
         return 'Hi, my name is %s, and I\'m "%s"' % (self.context.name,
                                                      self.context.size)
 
-class AddMammoth(grok.AddForm):
+class AddMammoth(grok.Form):
     grok.context(Zoo)
 
     form_fields = grok.AutoFields(Mammoth)

Modified: grok/trunk/src/grok/ftests/form/form.py
===================================================================
--- grok/trunk/src/grok/ftests/form/form.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/ftests/form/form.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -42,3 +42,4 @@
 
 class Display(grok.DisplayForm):
     pass
+

Modified: grok/trunk/src/grok/interfaces.py
===================================================================
--- grok/trunk/src/grok/interfaces.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/interfaces.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -36,9 +36,9 @@
     View = interface.Attribute("Base class for browser views.")
     XMLRPC = interface.Attribute("Base class for XML-RPC methods.")
     Traverser = interface.Attribute("Base class for custom traversers.")
+    Form = interface.Attribute("Base class for forms.")
     EditForm = interface.Attribute("Base class for edit forms.")
     DisplayForm = interface.Attribute("Base class for display forms.")
-    AddForm = interface.Attribute("Base class for add forms.")
 
 
 class IGrokErrors(interface.Interface):

Modified: grok/trunk/src/grok/meta.py
===================================================================
--- grok/trunk/src/grok/meta.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/meta.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -125,17 +125,13 @@
         view_context = util.determine_class_context(factory, context)
 
         factory.module_info = module_info
-
-        # some extra work to take care of if this view is a form
-        if util.check_subclass(factory, components.EditForm):
-            formlib.setup_editform(factory, view_context)
-        elif util.check_subclass(factory, components.DisplayForm):
-            formlib.setup_displayform(factory, view_context)
-        elif util.check_subclass(factory, components.AddForm):
-            formlib.setup_addform(factory, view_context)
-
         factory_name = factory.__name__.lower()
 
+        if util.check_subclass(factory, components.GrokForm):
+            # setup form_fields from context class if we've encountered a form
+            if getattr(factory, 'form_fields', None) is None:
+                factory.form_fields = formlib.get_auto_fields(view_context)
+
         # find templates
         template_name = util.class_annotation(factory, 'grok.template',
                                               factory_name)
@@ -150,42 +146,23 @@
                                 % (factory, template_name, factory_name),
                                 factory)
 
-        # we never accept a 'render' method for forms
-        if util.check_subclass(factory, components.Form):
-            if getattr(factory, 'render', None):
-                raise GrokError(
-                    "It is not allowed to specify a custom 'render' "
-                    "method for form %r. Forms either use the default "
-                    "template or a custom-supplied one." % factory,
-                    factory)
-
         if template:
-            if getattr(factory, 'render', None):
+            if (getattr(factory, 'render', None) and not
+                util.check_subclass(factory, components.GrokForm)):
                 # we do not accept render and template both for a view
+                # (unless it's a form, they happen to have render.
                 raise GrokError(
                     "Multiple possible ways to render view %r. "
                     "It has both a 'render' method as well as "
-                    "an associated template." % factory,
-                    factory)
+                    "an associated template." % factory, factory)
 
             templates.markAssociated(template_name)
             factory.template = template
         else:
             if not getattr(factory, 'render', None):
-                if util.check_subclass(factory, components.EditForm):
-                    # we have a edit form without template
-                    factory.template = formlib.defaultEditTemplate
-                elif util.check_subclass(factory, components.DisplayForm):
-                    # we have a display form without template
-                    factory.template = formlib.defaultDisplayTemplate
-                elif util.check_subclass(factory, components.AddForm):
-                    # we have an add form without template
-                    factory.template = formlib.defaultEditTemplate
-                else:
-                    # we do not accept a view without any way to render it
-                    raise GrokError("View %r has no associated template or "
-                                    "'render' method." % factory,
-                                    factory)
+                # we do not accept a view without any way to render it
+                raise GrokError("View %r has no associated template or "
+                                "'render' method." % factory, factory)
 
         view_name = util.class_annotation(factory, 'grok.name',
                                           factory_name)

Modified: grok/trunk/src/grok/templates/default_display_form.pt
===================================================================
--- grok/trunk/src/grok/templates/default_display_form.pt	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/templates/default_display_form.pt	2007-03-15 21:49:02 UTC (rev 73209)
@@ -11,7 +11,7 @@
       </tr>
     </thead>
     <tbody>
-      <tal:block repeat="widget view/form/widgets">
+      <tal:block repeat="widget view/widgets">
         <tr tal:define="odd repeat/widget/odd"
           tal:attributes="class python: odd and 'odd' or 'even'">
           <td class="fieldname">
@@ -26,7 +26,7 @@
     <tfoot>
       <tr class="controls">
         <td colspan="2" class="align-right">
-          <input tal:repeat="action view/form/actions" 
+          <input tal:repeat="action view/actions" 
             tal:replace="structure action/render" />
         </td>
       </tr>

Modified: grok/trunk/src/grok/templates/default_edit_form.pt
===================================================================
--- grok/trunk/src/grok/templates/default_edit_form.pt	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/templates/default_edit_form.pt	2007-03-15 21:49:02 UTC (rev 73209)
@@ -18,8 +18,8 @@
       Form status summary
     </div>
 
-    <ul class="errors" tal:condition="view/form/errors">
-      <li tal:repeat="error view/form/error_views">
+    <ul class="errors" tal:condition="view/errors">
+      <li tal:repeat="error view/error_views">
          <span tal:replace="structure error">Error Type</span>
       </li>
     </ul>
@@ -27,7 +27,7 @@
 
   <table class="form-fields">
     <tbody>
-      <tal:block repeat="widget view/form/widgets">
+      <tal:block repeat="widget view/widgets">
         <tr>
           <td class="label" tal:define="hint widget/hint">
             <label tal:condition="python:hint"
@@ -57,8 +57,8 @@
   </table>
 
   <div id="actionsView">
-    <span class="actionButtons" tal:condition="view/form/availableActions">
-      <input tal:repeat="action view/form/actions"
+    <span class="actionButtons" tal:condition="view/availableActions">
+      <input tal:repeat="action view/actions"
              tal:replace="structure action/render"
              />
     </span>

Modified: grok/trunk/src/grok/tests/form/customautoform.py
===================================================================
--- grok/trunk/src/grok/tests/form/customautoform.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/tests/form/customautoform.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -12,12 +12,13 @@
   >>> view = component.getMultiAdapter((Mammoth(), request), name='edit')
   >>> len(view.form_fields)
   1
-  >>> [w.__name__ for w in view.form.form_fields]
+  >>> [w.__name__ for w in view.form_fields]
   ['name']
+
   >>> view = component.getMultiAdapter((Mammoth2(), request), name='edit2')
   >>> len(view.form_fields)
   1
-  >>> [w.__name__ for w in view.form.form_fields]
+  >>> [w.__name__ for w in view.form_fields]
   ['size']
   
 """
@@ -46,4 +47,4 @@
     grok.context(Mammoth2)
 
     form_fields = grok.AutoFields(Mammoth).omit('name')
-    
+

Modified: grok/trunk/src/grok/tests/form/customform.py
===================================================================
--- grok/trunk/src/grok/tests/form/customform.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/tests/form/customform.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -12,7 +12,7 @@
   >>> view = component.getMultiAdapter((Mammoth(), request), name='edit')
   >>> len(view.form_fields)
   1
-  >>> [w.__name__ for w in view.form.form_fields]
+  >>> [w.__name__ for w in view.form_fields]
   ['name']
 
 """

Modified: grok/trunk/src/grok/tests/form/fields.py
===================================================================
--- grok/trunk/src/grok/tests/form/fields.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/tests/form/fields.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -8,9 +8,9 @@
   >>> from zope.publisher.browser import TestRequest
   >>> request = TestRequest()
   >>> view = component.getMultiAdapter((Mammoth(), request), name='edit')
-  >>> len(view.form.form_fields)
+  >>> len(view.form_fields)
   4
-  >>> [w.__name__ for w in view.form.form_fields]
+  >>> [w.__name__ for w in view.form_fields]
   ['a', 'b', 'g', 'd']
 
 """

Modified: grok/trunk/src/grok/tests/form/form.py
===================================================================
--- grok/trunk/src/grok/tests/form/form.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/tests/form/form.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -29,18 +29,18 @@
   >>> from zope.publisher.browser import TestRequest
   >>> request = TestRequest()
   >>> view = component.getMultiAdapter((manfred, request), name='edit')
-  >>> len(view.form.form_fields)
+  >>> len(view.form_fields)
   2
-  >>> [w.__name__ for w in view.form.form_fields]
+  >>> [w.__name__ for w in view.form_fields]
   ['name', 'size']
 
 It is important to keep the order of the fields:
 
   >>> view = component.getMultiAdapter(
   ...    (DifferentMammoth(), request), name='editdifferent')
-  >>> len(view.form.form_fields)
+  >>> len(view.form_fields)
   2
-  >>> [w.__name__ for w in view.form.form_fields]
+  >>> [w.__name__ for w in view.form_fields]
   ['size', 'name']
 
 """

Deleted: grok/trunk/src/grok/tests/form/norender.py
===================================================================
--- grok/trunk/src/grok/tests/form/norender.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/tests/form/norender.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -1,24 +0,0 @@
-"""
-Forms cannot define a render method. Here we show the case where the
-EditForm has an explicit template associate with it.
-
-  >>> grok.grok(__name__)
-  Traceback (most recent call last):
-  ...
-  GrokError: It is not allowed to specify a custom 'render' method for
-  form <class 'grok.tests.form.norender.Edit'>. Forms either use the default
-  template or a custom-supplied one.
-  
-"""
-
-import grok
-
-class Mammoth(grok.Model):
-    pass
-
-class Edit(grok.EditForm):
-    # not allowed to have a render method
-    def render(self):
-        return "this cannot be"
-    
-edit = grok.PageTemplate('Foo!')

Deleted: grok/trunk/src/grok/tests/form/norender2.py
===================================================================
--- grok/trunk/src/grok/tests/form/norender2.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/tests/form/norender2.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -1,22 +0,0 @@
-"""
-Forms cannot define a render method. Here we show the case where the
-EditForm has no explicit template associated with it:
-
-  >>> grok.grok(__name__)
-  Traceback (most recent call last):
-  ...
-  GrokError: It is not allowed to specify a custom 'render' method for
-  form <class 'grok.tests.form.norender2.Edit'>. Forms either use the default
-  template or a custom-supplied one.
-  
-"""
-
-import grok
-
-class Mammoth(grok.Model):
-    pass
-
-class Edit(grok.EditForm):
-    # not allowed to have a render method
-    def render(self):
-        return "this cannot be"

Modified: grok/trunk/src/grok/tests/form/schemaform.py
===================================================================
--- grok/trunk/src/grok/tests/form/schemaform.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/tests/form/schemaform.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -10,26 +10,26 @@
   >>> from zope.publisher.browser import TestRequest
   >>> request = TestRequest()
   >>> view = component.getMultiAdapter((manfred, request), name='edit')
-  >>> len(view.form.form_fields)
+  >>> len(view.form_fields)
   2
-  >>> [w.__name__ for w in view.form.form_fields]
+  >>> [w.__name__ for w in view.form_fields]
   ['name', 'size']
 
 When there are multiple schemas in play, we get all the fields:
 
   >>> view = component.getMultiAdapter((Manfred(), request), name='edit2')
-  >>> len(view.form.form_fields)
+  >>> len(view.form_fields)
   3
-  >>> [w.__name__ for w in view.form.form_fields]
+  >>> [w.__name__ for w in view.form_fields]
   ['can_talk', 'name', 'size']
 
 Schema fields and model level fields are combined:
 
   >>> view = component.getMultiAdapter(
   ...    (AnotherMammoth(), request), name='edit3')
-  >>> len(view.form.form_fields)
+  >>> len(view.form_fields)
   3
-  >>> [w.__name__ for w in view.form.form_fields]
+  >>> [w.__name__ for w in view.form_fields]
   ['can_talk', 'name', 'size']
 
 If the context is an interface instead of a model directly, the fields
@@ -37,9 +37,9 @@
 
   >>> view = component.getMultiAdapter(
   ...   (YetAnotherMammoth(), request), name='edit4')
-  >>> len(view.form.form_fields)
+  >>> len(view.form_fields)
   2
-  >>> [w.__name__ for w in view.form.form_fields]
+  >>> [w.__name__ for w in view.form_fields]
   ['alpha', 'beta']
 
 """

Modified: grok/trunk/src/grok/tests/form/schemainherit.py
===================================================================
--- grok/trunk/src/grok/tests/form/schemainherit.py	2007-03-15 20:13:56 UTC (rev 73208)
+++ grok/trunk/src/grok/tests/form/schemainherit.py	2007-03-15 21:49:02 UTC (rev 73209)
@@ -11,24 +11,24 @@
 Without AutoFields, just a simple edit form:
 
   >>> view = component.getMultiAdapter((manfred, request), name='edit')
-  >>> len(view.form.form_fields)
+  >>> len(view.form_fields)
   3
-  >>> [w.__name__ for w in view.form.form_fields]
+  >>> [w.__name__ for w in view.form_fields]
   ['name', 'size', 'speciality']
 
 With AutoFields:
 
   >>> view = component.getMultiAdapter((manfred, request), name='edit2')
-  >>> len(view.form.form_fields)
+  >>> len(view.form_fields)
   3
-  >>> [w.__name__ for w in view.form.form_fields]
+  >>> [w.__name__ for w in view.form_fields]
   ['name', 'size', 'speciality']
 
   >>> antimanfred = YetAnotherMammoth()
   >>> view = component.getMultiAdapter((antimanfred, request), name='edit3')
-  >>> len(view.form.form_fields)
+  >>> len(view.form_fields)
   3
-  >>> [w.__name__ for w in view.form.form_fields]
+  >>> [w.__name__ for w in view.form_fields]
   ['name', 'size', 'speciality']
 """
 import grok



More information about the Checkins mailing list