问题
I'm using wtforms, and I need to create a something that will generate a form definition based off information in a database; dynamic form creation. I'm getting a sense of what needs to be done and I've just started. I can create forms and use them with wtforms/flask but defining forms from data that will vary slightly from form to form is currently beyond my current skill level.
Has anyone done this and have some input to offer? Somewhat a vague question, no actual code yet. I haven't found any examples, but it is not impossible to do.
mass of variable data to be used in a form --> wtforms ---> form on webpage
EDIT:
So, a 'for example' we can use surveys. A survey consists of several SQLAlcehmy models. A survey is a model with any number of associated questions models(questions belong to surveys and it gets complicated for say, multiple choice questions). To simplify let's use simple json/dict pseudo code for:
{survey:"Number One",
questions:{
question:{type:truefalse, field:"Is this true or false"},
question:{type:truefalse, field:"Is this true or false"},
question:{type:text, field:"Place your X here"}
}
}
{survey:"Number Two",
questions:{
question:{type:text, field:"Answer the question"},
question:{type:truefalse, field:"Is this true or false"},
question:{type:text, field:"Place your email address here"}
}
}
Imagine instead of this, several hundred of varying lengths with 5+ field types. How to use WTForms to manage forms for this, or do I even need to use wtforms? I can define static forms as I need them, but not dynamically, yet.
As an aside I've done something like this in rails with simpleform but as I'm working in Python atm (on something different, I'm using the survey thing as an example, but the question/field/answer thing abstracts across a many types of inputs I've needed).
So yes it is possible I'll need to build some sort of factory, doing it will take me some time e.g.:
http://wtforms.simplecodes.com/docs/1.0.2/specific_problems.html
https://groups.google.com/forum/?fromgroups=#!topic/wtforms/cJl3aqzZieA
回答1:
Simply add the appropriate fields to the base form at run time. Here's a sketch of how you might do it (albeit much simplified):
class BaseSurveyForm(Form):
# define your base fields here
def show_survey(survey_id):
survey_information = get_survey_info(survey_id)
class SurveyInstance(BaseSurveyForm):
pass
for question in survey_information:
field = generate_field_for_question(question)
setattr(SurveyInstanceForm, question.backend_name, field)
form = SurveyInstanceForm(request.form)
# Do whatever you need to with form here
def generate_field_for_question(question):
if question.type == "truefalse":
return BooleanField(question.text)
elif question.type == "date":
return DateField(question.text)
else:
return TextField(question.text)
回答2:
class BaseForm(Form):
@classmethod
def append_field(cls, name, field):
setattr(cls, name, field)
return cls
from forms import TestForm
form = TestForm.append_field("do_you_want_fries_with_that",BooleanField('fries'))(obj=db_populate_object)
I use the extended class BaseForm for all my forms and have a convenient append_field function on class.
Returns the class with the field appended, since instances (of Form fields) can't append fields.
来源:https://stackoverflow.com/questions/12353603/dynamic-forms-from-variable-length-elements-wtforms