63

I am developing a flask registration form, and I receive an error:

error 405 method not found.

Code:

import os
# Flask
from flask import Flask, request, session, g, redirect, url_for, abort, \
     render_template, flash, Markup, send_from_directory, escape
from werkzeug import secure_filename

from cultura import app

# My app
from include import User

@app.route('/')
def index():
    return render_template('hello.html')

@app.route('/registrazione', methods=['POST']) 
def registration():
    if request.method == 'POST':
        username= request.form.username.data
        return render_template('registration.html', username=username)
    else :
        return render_template('registration.html')

registration.html:

<html>
<head> <title>Form di registrazione </title>
 </head> 

    <body>
    {{ username }}
    <form id='registration' action='/registrazione' method='post'>
    <fieldset >
    <legend>Registrazione utente</legend>
    <input type='hidden' name='submitted' id='submitted' value='1'/>
    <label for='name' >Nome: </label> 
    <input type='text' name='name' id='name' maxlength="50" /> <br>
    <label for='email' >Indirizzo mail:</label>
    <input type='text' name='email' id='email' maxlength="50" />
     <br>
    <label for='username' >UserName*:</label>
    <input type='text' name='username' id='username' maxlength="50" />
     <br>
    <label for='password' >Password*:</label>
    <input type='password' name='password' id='password' maxlength="50" />
    <br>
    <input type='submit' name='Submit' value='Submit' />

    </fieldset>
    </form>
    </body>
    </html>

when I visit localhost:5000/registrazione, I receive the error. What am I doing wrong?

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
Matteo
  • 1,153
  • 2
  • 9
  • 8
  • `methods=['POST']` is quite incompatible with `if request.method == 'POST': (...) else:` – njzk2 Feb 10 '14 at 23:08
  • 2
    so. you receive a method no allowed error, and you are doing a `GET` request on a route that was declared to accept only `POST`. do you understand why now? – njzk2 Feb 10 '14 at 23:09
  • yes and I add @app.route('/registrazione', methods=['GET', 'POST']) but now I receive error 500 Internal Server Error – Matteo Feb 10 '14 at 23:15
  • 1
    probably because `{{ username }}` is not defined, but you have the logs, so you should know. – njzk2 Feb 10 '14 at 23:24
  • I think is define because def registration(): if request.method == 'POST': username= request.form.username.data return render_template('registration.html', username=username) else : return render_template('registration.html') – Matteo Feb 10 '14 at 23:26
  • 1
    I think the `username.` **data** is wrong. Just using `username = request.form.username` should work. – Lukas Graf Feb 10 '14 at 23:31

7 Answers7

124

This is because you only allow POST requests when defining your route.

When you visit /registrazione in your browser, it will do a GET request first. Only once you submit the form your browser will do a POST. So for a self-submitting form like yours, you need to handle both.

Using

@app.route('/registrazione', methods=['GET', 'POST']) 

should work.

Lukas Graf
  • 30,317
  • 8
  • 77
  • 92
  • Thanks, now work. But if I edit def registration(): if request.method == 'POST': username= request.form.username.data return render_template('registration.html', username=username) else : return render_template('registration.html') I receive Internal Server Error – Matteo Feb 10 '14 at 23:11
  • 1
    @Matteo that's a different problem, please create a new question and include the stack trace. – Lukas Graf Feb 10 '14 at 23:21
3

change name of method registration

@app.route('/registrazione', methods=['POST']) 
def registrazione(): 
    if request.method == 'POST':
       username= request.form.username.data
       return render_template('registration.html', username=username)
   else :
       return render_template('registration.html')
RADHE
  • 31
  • 1
2

Just for people reading on it now. You have to render the /registrazione first, befor you can access the form data. Just write.

@app.route("/registrazione")
    def render_registrazione() -> "html":
        return render_template("registrazione.html")

before you define def registration(). Sequence is key. You can't access data before the even are available. This is my understanding of the problem.

nullbyte
  • 21
  • 1
  • 2
    Because I had the same problem or at least it seems similar to me, because I got the same error message and for me the provided solutions doesn't worked. But if I render the template with the form in my project first and then try to access the form data with a new function and post method everything worked fine. So I thought I can't post to something that doesn't exists. Why shouldn't I post my solution If the other's doesn't wirkt for me? – nullbyte Mar 03 '19 at 10:21
2

For the error 500 (internal server error) in

username = request.form.username 

write instead

username = request.args.get("username")
Fejs
  • 2,734
  • 3
  • 21
  • 40
Alonsome
  • 21
  • 2
1

Example of a flask app using wsgi with JQuery, Ajax and json:

activecalls.py

from flask import Flask, jsonify

application = Flask(__name__, static_url_path='')

@application.route('/')
def activecalls():
    return application.send_static_file('activecalls/active_calls_map.html')

@application.route('/_getData', methods=['GET', 'POST'])
def getData():
    #hit the data, package it, put it into json.
    #ajax would have to hit this every so often to get latest data.
    arr = {}
    arr["blah"] = []
    arr["blah"].append("stuff");

    return jsonify(response=arr)


if __name__ == '__main__':
    application.run()

Javascript json, /static/activecalls/active_calls_map.html:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>

<script>
$.ajax({
    //url : "http://dev.consumerunited.com/wsgi/activecalls.py/_getData",
    url : "activecalls.py/_getData",
    type: "POST",
    data : formData,
    datatype : "jsonp",
    success: function(data, textStatus, jqXHR)
    {
        //data - response from server
         alert("'" + data.response.blah + "'");
    },
    error: function (jqXHR, textStatus, errorThrown)
    {
         alert("error: " + errorThrown);

    }
});
</script>

When you run this. The alert box prints: "stuff".

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
1

I was also getting this error, I was going through all of this documentation and trying to sort this out, but at the end it was a silly mistake.

Below code was generating the 405 Method Not Allowed error

import requests
import json

URL = "http://hostname.com.sa/fetchdata/"

PARAMS = '{ "id":"111", "age":30, "city":"New Heaven"}'

response = requests.post(url = URL, json = PARAMS)

print(response.content)

It was due to an extra / at the end of url, when I removed it, it was gone. The below update on the requesting URL fixed it

URL = "http://hostname.com.sa/fetchdata"

akarahman
  • 235
  • 2
  • 15
0

I was stuck over same issue, I am showing my Login page route as default route and when I try to submit with default route then I got the issue because I had configured POST request on login route but not on the default application route and when I had added the 'POST' method configuration for my default route too, everything is working as expected. The configuration I had done is as follows:

@routes.route("/", methods=['GET', 'POST'] ) 
@routes.route("/admin-login", methods=['GET', 'POST'])
def admin_login():
...

Hope, this would help anyone facing the similar issue.

Kunal Soni
  • 81
  • 1
  • 4