Sourav Dey
Sourav Dey

Reputation: 427

How to store WTForm Form in session in Flask?

I need to store the result of a form in the session, but I keep getting TypeError: XXX is not JSON serializable for datetimes and Decimal fields. What is the right way to persist the form data between requests?

Here's my form:

class GiftRequestForm(Form):
    giftee_name = StringField('Name',
                          [validators.Required(), validators.length(min=4, max=25)])
    giftee_age = IntegerField('Age',
                          [validators.Required(),
                           validators.NumberRange(min=0, message="Age must be greater than 0")])
    giftee_sex = RadioField('Gender',
                        [validators.Required()],
                        choices=[('0', 'Male'), ('1', 'Female')])
    giftee_relationship = StringField('Relationship',
                                  [validators.Required(), validators.length(min=4, max=25)],
                                  description='Fill in the blank: The recipient is my _____.')
    event = StringField('Event',
                    [validators.Required(), validators.length(min=4, max=80)])
    event_date = DateField('Event Date',
                       [validators.Required()],
                       format='%Y-%m-%d',
                       description="Well have it to you at least four days before the event date.")
    budget = DecimalField('Budget $',
                      [validators.Required(),
                       validators.NumberRange(min=0, message="Budget must be greater than 0")])

In my view, I just want to do:

form = GiftRequestForm()
...
session['gift_request_form'] = form

This doesn't work at all because it doesn't seem like the GiftRequestForm is JSON serializable. Unfortunately, this doesn't work either:

session['gift_request_form'] = form.data

Because an element in my dictionary is a datetime and a Decimal type. So I always get a TypeError: datetime.date(2015, 9, 2) is not JSON serializable, or something similar for the Decimal field.

This seems like a standard pattern -- but I'm having alot of difficulty getting it to work. How should I do this?

Upvotes: 4

Views: 1629

Answers (1)

Sanna Keller-Heikkila
Sanna Keller-Heikkila

Reputation: 2594

You can cast the date and decimal as a string before storing it in the session. Then use strptime to convert the datetime from the string in session back to a date when you need to access it, and Decimal to convert the decimal values. It feels like a kludge to me with having to assemble the dictionary for session and recasting those values as strings, but with the limitations of serializing, I don't know of a better way.

Upvotes: 1

Related Questions