I try what Jay suggest, that works, but since eval is risky and not required, here what I come up with :
inputs_list = [] for a in my_dict: inputs_list.append(Field(my_dict[a]['field_name']+'_f1', type='boolean', widget=SQLFORM.widgets.checkboxes.widget, requires=IS_EMPTY_OR(IS_IN_SET([my_dict[a]['field_name_ui']]))) ) inputs_list.append(Field(my_dict[a]['field_name']+'_f2', db.ref_tab1, requires = IS_EMPTY_OR(IS_IN_DB(db,'ref_tab1.id ','%(MYREPRESENTFIELD1)s'))) ) inputs_list.append(Field(my_dict[a]['field_name']+'_f3', db.ref_tab2, requires = IS_EMPTY_OR(IS_IN_DB(db,'ref_tab2.id ','%(MYREPRESENTFIELD2)s'))) ) form = SQLFORM.factory( Field('other_ref_field_id', db.ref_other, requires=IS_IN_DB(db,'ref_other.sample_id','%(MYREPRESENT)s')), *inputs_list, # Unpack my generated fields here... formstyle='divs' ) No string, no eval. Richard On Sat, Apr 9, 2011 at 10:57 AM, Jay <jkel...@gmail.com> wrote: > I use this method for generating totally dynamic forms. > > 1. Create an array, say out > 2. Append "Field(<name>, <type>, <etc. etc.>)" to this array for all > fields I need - note this is a string, no function calls > 3. Wrap the above in an SQLFORM statement. > formstring = 'SQLFORM.factory(' +','.join(out)+')' > 4. Then eval the formstring to get the form > form = eval(formstring) > > You can use a similar method to create a table in the database > *** WARNING: I have not tested table creation, but it should work > **** WARNING: You can create the table, but because the definition of > the table in not in models dir, you will need to keep creating the > table each time you want to access the table. > If this table is to exist long term, you can write the generated text > (like formstring in #3 above) to a file and manually include it in a > model file. > > So to answer your question: > Do #1-2 as above > 3. Wrap the above in a define_table statement > deftabstring = "define_table('<tablename>,'" + ','.join(out)+')' -- > add "migrate=... as necessary > 4. Eval the deftabstring to create the table > mytab = eval(deftabstring) > > Assuming you use 'db' to get to the database, you can now user > db.<tablename> to get to your table. *Keep the second warning in > mind.* > > Aside: Many people out there do not like the use of eval, and will > criticize it right away. I use it when it is necessary. > NEVER USE EVAL WHEN THERE IS CHANCE OF USER INPUT IN UNPROCESSED FORM > BEING PART OF WHAT YOU EVAL, because you open a way to get hacked. > NEVER FORGET THIS! > > This is where programming gets interesting. > > Jay > > On Apr 9, 7:34 am, Serbitar <rserbi...@googlemail.com> wrote: > > Sorry, misstyped and sent the message early. So once again: > > > > I can create database fields from a list like this: > > > > list = ["a","b","c","d"] > > fields = [] > > for entry in list: > > fields += [Field(entry, type="string")] > > db.define_table('test', *fields) > > > > Now I want to have a virtual field for each field in the list. > > Any way to do this? As virtual field names are not strings but > > function names I got no idea how to do this. >