Edit: Category field is now able to repopulate. Made a mistake in retrieving the data. App.py has been edited.
I recently created an "edit post" form in which the user clicks on a link, and a few parameters are sent to a function. My function searches for the post and the wtform module attempts to repopulate the form with the data from the post targeted. It seems that the url (URLField), category (SelectField) and name (StringField) are able to repopulate, but the details (TextField) fields display a value of None. Can anyone guide me towards to right direction in terms of repopulating a flask-wtform?
Here was my attempt:
app.py
@app.route('/edit_post/<int:post_id>', methods=("GET","POST"))
@login_required
def edit_my_post(post_id):
posts = models.Post.select().where(models.Post.id == post_id)
if posts.count() == 0:
abort(404)
if post_user.id == current_user.id :
post = models.Post.select().where(models.Post.id == post_id).get()
form = forms.ProductForm(obj=post)
if form.validate_on_submit():
form.populate_obj(post)
query = models.Post.update(user = post.user.id,
name = form.name.data.strip(),
content = form.details.data.strip(),
url = form.url.data,
category = = form.category.data
).where(models.Post.id == post_id)
query.execute()
flash("Your post has been edited.", "success")
return redirect(url_for('index'))
else:
flash("Ay! Stay away from that post!","warning")
return redirect(url_for('index'))
return render_template("edit.html",form=form)
models.py
class Post(Model):
timestamp = DateTimeField(default=datetime.datetime.now)
user = ForeignKeyField(
rel_model = User,
related_name = 'posts'
)
name = TextField()
content = TextField()
upvotes = IntegerField(default=0)
url = TextField()
category = TextField()
class Meta:
database = DATABASE
order_by = ('-timestamp',)
forms.py
class ProductForm(Form):
name = StringField('Content Name', validators = [DataRequired()])
url = URLField(validators=[url()])
details = TextAreaField('Content Summary', validators = [DataRequired(),Length(max=140)])
category = SelectField("Choose a category that your content fits in.", choices=CATEGORIES,coerce=int)
edit.html
{% extends "layout.html" %}
{% from 'macros.html' import render_field %}
{% block content %}
<form method="POST" action="">
{{ form.hidden_tag() }}
{% for field in form %}
{{ render_field(field) }}
{% endfor %}
<br>
<button id="submit" type="submit">Edit Post</button>
</form>
{% endblock %}
Note: CATEGORIES is a (long) array of strings.
I had fixed the issue by simply renaming the details ProductForm field to the same name as the property on the Post form. So now the form code looks like this:
class ProductForm(Form):
name = StringField('Content Name', validators = [DataRequired()])
url = URLField(validators=[url()])
content = TextAreaField('Content Summary', validators = [DataRequired(),Length(max=140)])
category = SelectField("Choose a category that your content fits in.", choices=CATEGORIES,coerce=int)
And I renamed parts of the query to retrieve the data like so:
query = models.Post.update(user = post.user.id,
name = form.name.data.strip(),
content = form.content.data.strip(),
url = form.url.data,
category = form.category.data
).where(models.Post.id == post_id)
query.execute()