Question

I am new to wtforms, so I`ll really appreciate any help.

I need to display books names and near each put "Delete" button. I`ve read wtforms crash course but I have no idea how to solve my problem with it.

So I decided to do it other way - my best idea is to render to template a dict with id and name and on submit return id, but I still can`t do it. Code examples are below.

It`s view.py

@application.route('/delete', methods=['GET', 'POST'])
def delete():
    books_lib = mydatabase.get_all_books()
    form = DeleteForm(request.form)
    if request.method == 'POST':
        delete_id = form.id.data
        mydatabase.del_book(delete_id)
        return render_template('delete.html', form = form, books_lib = books_lib)
    return render_template('delete.html', form = form, books_lib = books_lib)

It`s template

<!DOCTYPE html>
<html>
<body>
    <h2>book to delete</h2>
<form action="/delete" name="delete" method="POST">
    {% if books_lib %}
        {% for id, book in books_lib.items() %}
            <p>{{book}}:<input type="submit" value="Delete" id="{{id}}">
        {% endfor%}
    {% endif %}
</form>
</body>
</html>

It`s form

class DeleteForm(Form):
     book = TextField("Book name", [validators.Length(min=2, max=25)])
     id = HiddenField("id")
Was it helpful?

Solution

Here is how I do it.

TEMPLATE

<p><a href="{{ url_for('delete_post', url=post.url) }}">delete</a></p>

View

# delete a post
@app.route('/<path:url>/d')
@login_required
def delete_post(url):
    post = Post.get_post(url)
    if post is None:
        flash('post not found')
        return redirect(url_for('home'))
    db.session.delete(post)
    db.session.commit()
    Topic.update_counts()
    flash('Your post has been deleted')
    return redirect(url_for('index'))

the url_for is a Flask function that generates a url and binds it to a function.

Soooo.... in a nutshell.

  1. template generates the delete path using the url_for function.
  2. the delete function is called when you visit the page.
  3. message flashes to template saying delete complete.

to answer your original question....

if you simply want to pass a list of ids to your template....

First, create the display function.

@app.route('/index')
def index():
    posts = Post.query.order_by(Post.pub_date.desc())  #SQLAlchemy query.
    return render_template('index.html', posts=posts) #sends all posts to template.

Now in your template you can generate a list of post.ids.

    {% for post in posts %}
        {{post.id})
    {% endfor %}

to add a delete link next to each item in your list use url_for.

{% for post in posts %}    
<p>{{post.id}) <a href="{{ url_for('delete_post', id=post.id) }}">delete</a></p>
{% endfor %}

In this case I use post id instead of the post.url to identify the specific post I want to delete, so don't forget to modify your @app.route in your delete function.

@app.route('/<int:id>/delete')

Notice this solution does not require a form. You only need a form if your want to do bulk deletes with check boxes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top