> Is it possible to build a page with formlib, widgets, and a page > template without using the ZODB or ZMI. I have been trying for awhile > to accomplish this with no luck. I want to build an edit form that > shows results from a postgresql database which does not add any > objects within the zodb. If anyone can help or has any examples I > would really appreciate it. Recently I started to write real application that uses my product for RDBMS interaction (I've sent you links to very first (and very unstable) version of this). Because of doing real work I did some fixes and changes to my general product. I called this 'dbformlib'. First stable version is available at: http://dbcrudbase.googlecode.com/svn/tags/dbformlib_1_0/ I know that you may hate this product already because of it's recent unstability (but it was still developement) but if you want to give it second try then take a look at it now.
In general it is supposed to create one content object that is a gateway between user and RDBMS. Each content object handles one(!) form (but a lot of rows from database). Eg. you have table Account in RDBMS so you will create 'account_content object' that will have few SQLScripts inside to call: select, update, insert, delete statements on Account table. Then you will create views for edit, add, delete (just like in formlib). Only difference is that for forms other than 'add' you need row id to know which row should be returned from database. row 'id' is called Entry parameter by me, because it has to appear in request like: http://localhost/mysite/mycontentobj/edit.html?in.id=1 thanks to this, your's select can be like: select * from Account where id=<dtml-sqlvar id type="int"> Simple usage may be seen at application located at: docs/sample but this doesn't use real database. Description is at docs/sample/Readme.txt. Below some code from my real app that uses dbformlib. One important thing is connectionName. You have to create (and register at your site) database adapter. It's name is then used as 'connectionName'. In my case I have site that during add, creates my content and sets connectionName but you may use hardcoded value instead of self.Connection while creating SQLScripts. For a start you may take 'Sample DBFormlib' application and create some SQLMethods in it and just call them with hardcoded 'connectionname'. interfaces.py ----------------------- from zope.schema import TextLine, URI from dbformlib.fields import EntryField from dbformlib.interfaces import IDBFormlibContent class IAccount(IDBFormlibContent): """ Content object interface """ id = EntryField(title=u"id") cancel_url = EntryField(title=u"cancel_url", required=False) aplikacja = TextLine(title=u"Aplikacja") adres = URI(title=u"Adres") mycontent.py ----------------------- from dbformlib.dbformlib import DBFormlibContent from interfaces import IAccount class Account(DBFormlibContent): zope.interface.implements(IMonitorConfDB) def setup(self): # select sql = 'select * from monitor_conf where id=<dtml-sqlvar id type="int">' sqlArguments = 'id' sqlQuery = SQLScript(self.connectionName, sql, sqlArguments) self['get_config_entry'] = sqlQuery notify(ObjectCreatedEvent(sqlQuery)) # update sql ='''update monitor_conf set aplikacja=<dtml-sqlvar aplikacja type="string">, adres=<dtml-sqlvar adres type="string"> where id=<dtml-sqlvar id type="int">''' sqlArguments = 'id aplikacja adres' sqlQuery = SQLScript(self.connectionName, sql, sqlArguments) self['set_config_entry'] = sqlQuery notify(ObjectCreatedEvent(sqlQuery)) def _get_form_data(self, crud_id, in_params={}): ret_dict={} if crud_id=='edit': try: res = self['get_config_entry'](id=in_params['id']) if res: ret_dict['aplikacja']=res[0].APLIKACJA ret_dict['adres']=res[0].ADRES return ret_dict raise UserError('No data for this ID!') except DatabaseException, err: raise UserError(u'DB error') else: return {'adres':'http://'} def _set_form_data(self, crud_id, data, errors=[]): try: if crud_id=='edit': self['set_config_entry'](id=data['id'], aplikacja=data['aplikacja'], adres=data['adres']) except DatabaseException, err: errors.append(u'db error...') views.py --------------- from zope.formlib import form from zope.app.form.browser import BytesWidget from zope.traversing.browser.absoluteurl import absoluteURL from dbformlib.browser import DBFormlibEditForm from monitor.interfaces import IAccount class WideBytesWidget(BytesWidget): displayWidth = 80 class AccountEditForm(DBFormlibEditForm): label = u'Edit my data' actions = DBFormlibEditForm.actions def define_fields(self): self.form_fields = form.Fields(IAccount) self.form_fields['adres'].custom_widget = WideBytesWidget @form.action(u'Cancel', validator=lambda *a: ()) # hack to omit validation def handle_cancel_action(self, action, data): data = self.get_data_obj().get_data() absoluteURL(self.context, self.request) if data['cancel_url']: self.request.response.redirect(data['cancel_url']) return None configure.zcml ------------------------- ... <browser:page name="edit.html" for="..interfaces.IAccount" class=".views.AccountEditForm" permission="zope.View" /> ... -- Maciej Wisniowski _______________________________________________ Zope3-users mailing list [email protected] http://mail.zope.org/mailman/listinfo/zope3-users
