librelist archives

« back to archive

Create a MultiDict in Flask

Create a MultiDict in Flask

From:
Guy Jacks
Date:
2013-09-08 @ 21:29
Short Question:  How do I create the werkzeug MultiDict from a flask view?

Background in case someone can tell me a better way to do this:

Usecase: My users can answer a set of 3 randomly generated questions
(pulled from a database).

My Solution:

In my view I'm dynamically adding TextArea fields to my form (wtforms).
 The user will answer a question in each of these fields.

There are two types of questions.  Ones that the user has answered in the
past (previous questions) and ones that she has not (new questions).

In the case of new questions, the name of the field is "new-qid" where gid
is the db id for the question.

In the case of previous questions, the name of the field is
"prev-aid-question-qid" where aid is the db id for the user's answer to the
question.  I also set the default value of the TextArea to the user's
stored answer.

So the form renders with 3 textareas, we'll say 2 new questions and 1
previous question.

<textarea name="new-23"></textarea>
<textarea name="new-12"></textarea>
<textarea name="prev-921-question-42">previous answer text here</textarea>

The user fills answers the new questions and changes her answer to the
previous question.

Great, no problem.  I loop through the request.form fields and do all the
magic fieldname parsing and create or update answers in the database
accordingly.  Everything up to this point is working.

Next, I want to render the form to the user with her answers all filled in.
 There is slight problem though.  Her answers to "new-23" and "new-12" are
no longer new since she has saved her answers to them.  My solution is to
dynamically add the TextArea fields to the form while changing the field
names from "new-23" and "new-12" to "prev-892-question-23" and
"prev-902-question-12".  I then create the form passing it the request.form
data and render the template...

In summary, I'm trying to redisplay the form with her answers to all three
questions.

And here lies my problem.  request.form does not contain the newly
generated form field names.  It still contains "new-23" and "new-12".  I
also cannot change them because request.form is immutable.  Okay, so I
tried to just manually create a dictionary with the new field value pair
and pass it to my form in place of request.form.  That won't work either,
because request.form is not a dict.  It's a MultiDict.  Next I read the
docs and it appears that MultiDict is a custom dict available from
Werkzeug.  This is where I'm stuck.  I can't figure out how to create a
MultiDict in my Flask view.  Obviously from Flask import MultiDict does not
work!

I hope that someone has a better way for me to do all this but if not,
hopefully I will be able to simply create a MultiDict and pass it to my
form in place of request.form.  I would also like to know if there is a way
to modify request.form without jumping through rings of fire.

I know this is a complicated question so I can hop on IRC to talk it
through if someone wants to help me.

Thanks in advance.

Re: [flask] Create a MultiDict in Flask

From:
Daniel Arbanas
Date:
2013-09-10 @ 20:33
On Sun, Sep 8, 2013 at 11:29 PM, Guy Jacks <guy.jacks@gmail.com> wrote:

> Short Question:  How do I create the werkzeug MultiDict from a flask view?
>
> Background in case someone can tell me a better way to do this:
>
> Usecase: My users can answer a set of 3 randomly generated questions
> (pulled from a database).
>
> My Solution:
>
> In my view I'm dynamically adding TextArea fields to my form (wtforms).
>  The user will answer a question in each of these fields.
>
> There are two types of questions.  Ones that the user has answered in the
> past (previous questions) and ones that she has not (new questions).
>
> In the case of new questions, the name of the field is "new-qid" where gid
> is the db id for the question.
>
> In the case of previous questions, the name of the field is
> "prev-aid-question-qid" where aid is the db id for the user's answer to the
> question.  I also set the default value of the TextArea to the user's
> stored answer.
>
> So the form renders with 3 textareas, we'll say 2 new questions and 1
> previous question.
>
> <textarea name="new-23"></textarea>
> <textarea name="new-12"></textarea>
> <textarea name="prev-921-question-42">previous answer text here</textarea>
>
> The user fills answers the new questions and changes her answer to the
> previous question.
>
> Great, no problem.  I loop through the request.form fields and do all the
> magic fieldname parsing and create or update answers in the database
> accordingly.  Everything up to this point is working.
>
> Next, I want to render the form to the user with her answers all filled
> in.  There is slight problem though.  Her answers to "new-23" and "new-12"
> are no longer new since she has saved her answers to them.  My solution is
> to dynamically add the TextArea fields to the form while changing the field
> names from "new-23" and "new-12" to "prev-892-question-23" and
> "prev-902-question-12".  I then create the form passing it the request.form
> data and render the template...
>
> In summary, I'm trying to redisplay the form with her answers to all three
> questions.
>
> And here lies my problem.  request.form does not contain the newly
> generated form field names.  It still contains "new-23" and "new-12".  I
> also cannot change them because request.form is immutable.  Okay, so I
> tried to just manually create a dictionary with the new field value pair
> and pass it to my form in place of request.form.  That won't work either,
> because request.form is not a dict.  It's a MultiDict.  Next I read the
> docs and it appears that MultiDict is a custom dict available from
> Werkzeug.  This is where I'm stuck.  I can't figure out how to create a
> MultiDict in my Flask view.  Obviously from Flask import MultiDict does not
> work!
>
> I hope that someone has a better way for me to do all this but if not,
> hopefully I will be able to simply create a MultiDict and pass it to my
> form in place of request.form.  I would also like to know if there is a way
> to modify request.form without jumping through rings of fire.
>
> I know this is a complicated question so I can hop on IRC to talk it
> through if someone wants to help me.
>
> Thanks in advance.
>



Hi.

I think you are looking for this
http://wtforms.simplecodes.com/docs/1.0.4/forms.html#wtforms.form.BaseForm.process

from werkzeug.datastructures import MultiDict
myform.process(MultiDict(mydict))

where mydict is a dictionary with the new field value pair.

Regards.

Re: [flask] Create a MultiDict in Flask

From:
Guy Jacks
Date:
2013-09-12 @ 01:04
Hi Daniel,

Thank you so much.  I was able to import the MultiDict from Werkzeug as
follows:

from werkzeug import MultiDict

I then simply created the MultiDict and passed it to form like:

md = MultiDict()
md.add(...)
md.add(...)
form = UserForm(md, ...)

Later,

Guy


On Tue, Sep 10, 2013 at 4:33 PM, Daniel Arbanas <daniel.arbanas@gmail.com>wrote:

>
> On Sun, Sep 8, 2013 at 11:29 PM, Guy Jacks <guy.jacks@gmail.com> wrote:
>
>> Short Question:  How do I create the werkzeug MultiDict from a flask view?
>>
>> Background in case someone can tell me a better way to do this:
>>
>> Usecase: My users can answer a set of 3 randomly generated questions
>> (pulled from a database).
>>
>> My Solution:
>>
>> In my view I'm dynamically adding TextArea fields to my form (wtforms).
>>  The user will answer a question in each of these fields.
>>
>> There are two types of questions.  Ones that the user has answered in the
>> past (previous questions) and ones that she has not (new questions).
>>
>> In the case of new questions, the name of the field is "new-qid" where
>> gid is the db id for the question.
>>
>> In the case of previous questions, the name of the field is
>> "prev-aid-question-qid" where aid is the db id for the user's answer to the
>> question.  I also set the default value of the TextArea to the user's
>> stored answer.
>>
>> So the form renders with 3 textareas, we'll say 2 new questions and 1
>> previous question.
>>
>> <textarea name="new-23"></textarea>
>> <textarea name="new-12"></textarea>
>> <textarea name="prev-921-question-42">previous answer text here</textarea>
>>
>> The user fills answers the new questions and changes her answer to the
>> previous question.
>>
>> Great, no problem.  I loop through the request.form fields and do all the
>> magic fieldname parsing and create or update answers in the database
>> accordingly.  Everything up to this point is working.
>>
>> Next, I want to render the form to the user with her answers all filled
>> in.  There is slight problem though.  Her answers to "new-23" and "new-12"
>> are no longer new since she has saved her answers to them.  My solution is
>> to dynamically add the TextArea fields to the form while changing the field
>> names from "new-23" and "new-12" to "prev-892-question-23" and
>> "prev-902-question-12".  I then create the form passing it the request.form
>> data and render the template...
>>
>> In summary, I'm trying to redisplay the form with her answers to all
>> three questions.
>>
>> And here lies my problem.  request.form does not contain the newly
>> generated form field names.  It still contains "new-23" and "new-12".  I
>> also cannot change them because request.form is immutable.  Okay, so I
>> tried to just manually create a dictionary with the new field value pair
>> and pass it to my form in place of request.form.  That won't work either,
>> because request.form is not a dict.  It's a MultiDict.  Next I read the
>> docs and it appears that MultiDict is a custom dict available from
>> Werkzeug.  This is where I'm stuck.  I can't figure out how to create a
>> MultiDict in my Flask view.  Obviously from Flask import MultiDict does not
>> work!
>>
>> I hope that someone has a better way for me to do all this but if not,
>> hopefully I will be able to simply create a MultiDict and pass it to my
>> form in place of request.form.  I would also like to know if there is a way
>> to modify request.form without jumping through rings of fire.
>>
>> I know this is a complicated question so I can hop on IRC to talk it
>> through if someone wants to help me.
>>
>> Thanks in advance.
>>
>
>
>
> Hi.
>
> I think you are looking for this
> 
http://wtforms.simplecodes.com/docs/1.0.4/forms.html#wtforms.form.BaseForm.process
>
> from werkzeug.datastructures import MultiDict
> myform.process(MultiDict(mydict))
>
> where mydict is a dictionary with the new field value pair.
>
> Regards.
>



-- 
Internet Strategist and Applications Architect

mobile: 614.448.7649
guy.jacks@gmail.com
gtalk: guy.jacks
skype: guy.jacks