4

I am using a flask framework, and can't seem to delete rows from the database. The code below gives a 405 error: "The method is not allowed for the requested URL." Any ideas?

In the py:

@app.route('/delete/<postID>', methods=['POST'])
def delete_entry():
    if not session.get('logged_in'):
        abort(401)
    g.db.execute('delete from entries WHERE id = ?', [postID])
    flash('Entry was deleted')
    return redirect(url_for('show_entries', post=post))

In the html:

<a href="/delete/{{ entry.id }}"><h3>delete</h3></a>

4 Answers 4

4

Clicking <a href...>delete</a> will issue a GET request, and your delete_entry method only responds to POST.

You need to either 1. replace the link with a form & submit button or 2. have the link submit a hidden form with JavaScript.

Here's how to do 1:

<form action="/delete/{{ entry.id }}" method="post">
    <input type="submit" value="Delete />
</form>

Here's how to do 2 (with jQuery):

$(document).ready(function() {
    $("a.delete").click(function() {
        var form = $('<form action="/delete/' + this.dataset.id + '" method="post"></form>');
        form.submit();
    });
});

...

<a href="#delete" class="delete" data-id="{{ entry.id }}">Delete</a>

One thing you should not do is make your delete_entry method respond to GET. GETs are meant to be idempotent (are safe to run repeatedly and don't perform destructive actions). Here's a question with some more details.

Sign up to request clarification or add additional context in comments.

1 Comment

Option 1 is kinda nice. but only problem is when logging... it doesn't show it as DELETE but POST...
2

Alternatively, change POST to DELETE to get you going.

@app.route('/delete/<postID>', methods=['DELETE'])

Ideally, you should use HTTP DELETE method.

2 Comments

Here are some reasons why GET shouldn't be used for modifying data: stackoverflow.com/questions/705782/…
@user805981, true as in this question: stackoverflow.com/questions/5162960/…. You would use ajax to issue 'delete' than using form method itself.
1

I used flaskr as a base for my Flask project (as it looks like you did as well).

In the .py:

@app.route('/delete', methods=['POST'])
def delete_entry():
if not session.get('logged_in'):
    abort(401)
g.db.execute('delete from entries where id = ?', [request.form['entry_id']])
g.db.commit()
flash('Entry deleted')
return redirect(url_for('show_entries'))

In the HTML:

<form action="{{ url_for('delete_entry') }}" method=post class=delete-entry>
    <input type="hidden" name="entry_id" value="{{ entry.id }}">
    <input type="submit" value="Delete" />
</form>

I wanted a button, but you could easily use a link with the solution here.

Comments

0

A simple <a href= link in HTML submits a GET request, but your route allows only PUT requests.

<a> does not support PUT requests. You have to submit the request with a form and/or with JavaScript code. (See Make a link use POST instead of GET.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.