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.
>

Reply via email to