Commits

Gael Pasgrimaud committed a0edd23

add forms

  • Participants
  • Parent commits 850b428

Comments (0)

Files changed (12)

File formalchemy/ext/pyramid/__init__.py

 from pyramid.view import view_config
 from pyramid.renderers import render
 from pyramid.renderers import get_renderer
+from pyramid import httpexceptions as exc
 
 try:
     from formalchemy.ext.couchdb import Document
         self.__name__ = name
         self.__parent__ = None
     def __getitem__(self, item):
+        if item in ('new',):
+            raise KeyError()
         model = ModelItem(self.request, item)
         model.__parent__ = self
         return model
                     return model
         elif hasattr(self.model, self.model_name):
             return getattr(self.model, self.model_name)
-        abort(404)
+        raise exc.HTTPNotFound()
 
     def get_fieldset(self, id):
         if self.forms and hasattr(self.forms, self.model_name):
         model = self.get_model()
         if id:
             model = S.query(model).get(id)
-        return model or abort(404)
+        if model:
+            return model
+        raise exc.HTTPNotFound()
 
     def get_fieldset(self, id=None):
         """return a ``FieldSet`` object bound to the correct record for ``id``.
             pager = kwargs.pop('pager')
         return self.render_grid(format=format, fs=fs, id=None, pager=pager)
 
-    @view_config(name='', request_method='POST', **VIEW_ARGS)
-    @view_config(name='', request_method='PUT', **VIEW_ARGS)
-    def create(self, request):
+    def create(self):
         """REST api"""
+        request = self.request
         fs = self.get_add_fieldset()
 
         if format == 'json' and request.method == 'PUT':
                 return self.render(format=format, fs=fs)
         return self.render(format=format, fs=fs, action='new', id=None)
 
-    @view_config(name='', request_method='DELETE', **VIEW_ARGS)
     def delete(self, id, format='html', **kwargs):
         """REST api"""
         record = self.get(id)
         fs.readonly = True
         return self.render(fs=fs, action='show', id=id)
 
-    @view_config(name='new', request_method='GET', **VIEW_ARGS)
     def new(self, format='html', **kwargs):
         """REST api"""
         fs = self.get_add_fieldset()
         fs = fs.bind(session=self.Session())
         return self.render(format=format, fs=fs, action='new', id=None)
 
-    @view_config(name='edit', request_method='GET', **VIEW_ARGS)
     def edit(self, id=None, format='html', **kwargs):
         """REST api"""
         fs = self.get_fieldset(id)
         return self.render(format=format, fs=fs, action='edit', id=id)
 
-    @view_config(name='', request_method='POST', **VIEW_ARGS)
-    @view_config(name='', request_method='PUT', **VIEW_ARGS)
     def update(self, id, format='html', **kwargs):
         """REST api"""
+        request = self.request
         fs = self.get_fieldset(id)
         if format == 'json' and request.method == 'PUT' and '_method' not in request.GET:
             data = json.load(request.body_file)

File formalchemy/ext/pyramid/configure.zcml

     />
 
 <view
+    name="new"
+    route_name="fa_admin"
+    context=".ModelListing"
+    view=".ModelView"
+    attr="new"
+    request_method="GET"
+    renderer="formalchemy:ext/pyramid/forms/new.pt"
+    />
+
+<view
+    name=""
+    route_name="fa_admin"
+    context=".ModelListing"
+    view=".ModelView"
+    attr="create"
+    request_method="POST"
+    />
+
+<view
+    name="edit"
+    route_name="fa_admin"
+    context=".ModelListing"
+    view=".ModelView"
+    attr="edit"
+    request_method="GET"
+    renderer="formalchemy:ext/pyramid/forms/edit.pt"
+    />
+
+<view
     name=""
     route_name="fa_admin"
     context=".ModelItem"

File formalchemy/ext/pyramid/forms/edit.pt

   <body>
     <div metal:fill-slot="main">
       <form action="" method="POST" enctype="multipart/form-data">
-      <div tal:content="structure fs.render()" />
-      <div metal:use-macro="main.macros['buttons']">
-      </div>
+        <div tal:content="structure fs.render()" />
+        <div metal:use-macro="main.macros['buttons']">
+        </div>
+      </form>
     </div>
   </body>
 </html>

File formalchemy/ext/pyramid/forms/listing.pt

       <div class="ui-pager" tal:content="structure pager" />
       <table class="layout-grid" tal:content="structure fs.render()" />
       <p>
-        <a class="ui-widget-header ui-widget-link ui-corner-all" href="./new">
+        <a class="ui-widget-header ui-widget-link ui-corner-all"
+           tal:attributes="href request.route_url('fa_admin', traverse='%s/new' % request.model_name)">
             <span class="ui-icon ui-icon-circle-plus"></span>
             ${F_('New')} ${model_name}
         </a>

File formalchemy/ext/pyramid/forms/master.pt

     <a class="ui-widget-header ui-widget-link ui-widget-button ui-corner-all" href="#">
       <input type="submit" value="${F_('Save')}" />
     </a>
-    <a class="ui-widget-header ui-widget-link ui-corner-all" href="./..">
+    <a class="ui-widget-header ui-widget-link ui-corner-all"
+       tal:attributes="href request.route_url('fa_admin', traverse=request.model_name)">
       <span class="ui-icon ui-icon-circle-arrow-w"></span>
       ${F_('Cancel')}
     </a>

File formalchemy/ext/pyramid/forms/models.pt

     <div metal:fill-slot="main">
       <div tal:repeat="item models">
         <div>
-          <a tal:attributes="href string:${item}"
+          <a tal:attributes="href request.route_url('fa_admin', traverse=item)"
              tal:content="item"></a>
         </div>
       </div>

File formalchemy/ext/pyramid/forms/new.pt

+<html metal:use-macro="main.macros['master']">
+  <body>
+    <div metal:fill-slot="main">
+      <form method="POST" enctype="multipart/form-data"
+            tal:attributes="action request.route_url('fa_admin', traverse=request.model_name)"
+        >
+        <div tal:content="structure fs.render()" />
+        <div metal:use-macro="main.macros['buttons']">
+        </div>
+      </form>
+    </div>
+  </body>
+</html>
+
+

File pyramidapp/buildout.cfg

 parts = eggs
 develop =
   ../../FormAlchemy
-  ../pyramid
+#  ../pyramid
   .
 
 [eggs]
     Pyramid
     FormAlchemy
     pyramidapp
+    webtest
     nose

File pyramidapp/development.ini

 reload_templates = true
 mako.directories = pyramidapp:templates
 debug_authorization = false
-debug_notfound = false
+debug_notfound = true
 debug_templates = true
 default_locale_name = en
 db_string = sqlite:///%(here)s/tutorial.db
 
 [pipeline:main]
 pipeline =
-    egg:WebError#evalerror
+#    egg:WebError#evalerror
     egg:repoze.tm2#tm
     pyramidapp
 

File pyramidapp/pyramidapp/__init__.py

                        action='index')
     config.add_subscriber('pyramidapp.subscribers.add_renderer_globals',
                           'pyramid.events.BeforeRender')
+    config.load_zcml('formalchemy:configure.zcml')
+    config.add_route('fa_admin', '/admin/*traverse',
+                     factory='formalchemy.ext.pyramid.AdminView')
+    config.registry.settings.update({
+        'fa.models': config.maybe_dotted('pyramidapp.models'),
+        'fa.session_factory': config.maybe_dotted('pyramidapp.models.DBSession'),
+        })
+
     config.end()
     return config.make_wsgi_app()

File pyramidapp/pyramidapp/models.py

     def by_name(cls, name=None):
         return DBSession.query(cls).filter(cls.name == name).first()
 
+class Foo(Base):
+    __tablename__ = 'foo'
+    id = Column(Integer, primary_key=True)
+    bar = Column(Unicode(255))
+
 def populate():
     model = MyModel(name=u'root', value=55)
     DBSession.add(model)

File pyramidapp/pyramidapp/tests.py

+import os
 import unittest
+from webtest import TestApp
+from pyramidapp import main
+from paste.deploy import loadapp
+
+dirname = os.path.abspath(__file__)
+dirname = os.path.dirname(dirname)
+dirname = os.path.dirname(dirname)
+
+class TestController(unittest.TestCase):
+
+    def setUp(self):
+        app = loadapp('config:%s' % os.path.join(dirname, 'development.ini'))
+        self.app = TestApp(app)
+
+    def test_index(self):
+        # index
+        resp = self.app.get('/admin/')
+        resp.mustcontain('/admin/Foo')
+        resp = resp.click('Foo')
+
+        ## Simple model
+
+        # add page
+        resp.mustcontain('/admin/Foo/new')
+        resp = resp.click('New Foo')
+        resp.mustcontain('/admin/Foo"')
+        form = resp.forms[0]
+        form['Foo--bar'] = 'value'
+        resp = form.submit()
+        assert resp.headers['location'] == 'http://localhost/admin/Foo'
+
+        # model index
+        resp = resp.follow()
+        resp.mustcontain('<td>value</td>')
+
+        # edit page
+        form = resp.forms[0]
+        resp = form.submit()
+        form = resp.forms[0]
+        form['Foo-1-bar'] = 'new value'
+        form['_method'] = 'PUT'
+        resp = form.submit()
+        resp = resp.follow()
+
+        # model index
+        resp.mustcontain('<td>new value</td>')
+
+        # delete
+        resp = self.app.get(url('models', model_name='Foo'))
+        resp.mustcontain('<td>new value</td>')
+        resp = resp.forms[1].submit()
+        resp = resp.follow()
+
+        assert 'new value' not in resp, resp
+
+
 
 class MyHandlerTests(unittest.TestCase):
     def setUp(self):