Pass custom object to WTForm

3.5k Views Asked by At

I need to pass an object from my database to my form, from which i want to read the default values out. My current code looks like this:

My initialisation:

form = EditEventForm(event)

And my form class:

class EditEventForm(FlaskForm):
    def __init__(self, event):
        self.event = event

    name = StringField('Name', validators=[DataRequired()],     default=self.event.name)
    description = TextAreaField('Description', validators=[DataRequired()], default=self.event.description)
    street = StringField('Street and number', validators=[DataRequired()], default=self.event.street)
    city = StringField('City', validators=[DataRequired()], default=self.event.city)
    time = StringField('Time', validators=[DataRequired()], default=self.event.time)

But obviously, the form cannot access the self-context. Is there another way i can achieve it so my fields can read the data out from a passed object?

2

There are 2 best solutions below

3
On BEST ANSWER

If your task is just to populate form with default data you can do it like this:

from flask_wtf import Form
from wtforms import StringField, TextAreaField
from wtforms.validators import DataRequired

class EditEventForm(Form):
    name = StringField('Name', validators=[DataRequired()])
    description = TextAreaField('Description', validators=[DataRequired()])
    street = StringField('Street and number', validators=[DataRequired()])
    city = StringField('City', validators=[DataRequired()])
    time = StringField('Time', validators=[DataRequired()])

And then populate your newly created form with desired data

form = EditEventForm()
form.name.data = event.name
form.description.data = event.description
form.street.data = event.street
form.city.data = event.city
form.time.data = event.time

Edit

As was suggested in the comments the stated above pattern is bad because when either model or form object is changed then all instances of form creation must be tracked down. One can use someting like this instead:

# attributes of the event object matching form field names will be used for field values
form = EditEventForm(obj=event)

# populates the attributes of the passed obj with data from the form’s fields
form.populate_obj(event)

From the documentation:

Note: This is a destructive operation; Any attribute with the same name as a field will be overridden. Use with caution.

1
On

From the FineManual:

init(formdata=None, obj=None, prefix='', data=None, meta=None, **kwargs) Parameters:
(...) obj – If formdata is empty or not provided, this object is checked for attributes matching form field names, which will be used for field values.