405 Method Not Allowed Error in post request while creating user - python

I'm making a user registration form in which I have made a post request to get the user input data in a print out form but 405 Method Not allowed error causing the problem. I'm a newbie so that's why I couldn't figure out what's going wrong.
CONTROLLER CLASS:
import web
from Models import RegisterModel
urls = (
"/", "Home",
"/register", "Register",
"/post", "PostRegistration",
)
render = web.template.render("Views/Templates", base="MainLayout")
app = web.application(urls, globals())
# Classes/routes
class Home:
def GET(self):
return render.Home()
class Register:
def GET(self):
return render.Register()
class PostRegistration:
def POST(self):
data = web.input()
reg_model = RegisterModel.RegisterModelCls()
reg_model.insert_user(data)
return data.username
if __name__ == "__main__":
app.run()
Registration form:
<div class="container">
<h2>Register Account</h2>
<br /><br />
<form>
<div class="form-group label-static is-empty">
<label for="username" class="control-label">Username</label>
<input id="username" name="username" class="form-control"
type="text" placeholder="Choose a username" />
</div>
<div class="form-group label-static is-empty">
<label for="display_name" class="control-label">Full Name</label>
<input id="display_name" name="name" class="form-control"
type="text" placeholder="Enter your full name" />
</div>
<div class="form-group label-static is-empty">
<label for="email" class="control-label">Email Address</label>
<input id="email" name="email" class="form-control" type="email"
placeholder="Enter your Email" />
</div>
<div class="form-group label-static is-empty">
<label for="password" class="control-label">Password</label>
<input id="password" name="password" class="form-control"
type="password" placeholder="Make a password" />
</div>
<a type="submit" href="/post" class="btn btn-info waves-effect"
>Submit <div class="ripple-container"></div></a>
</form>
</div>
RegistrationModel.py class (which suppose to print the user input)
import pymongo
from pymongo import MongoClient
class RegisterModelCls:
def insert_user(self, data):
print("data is: " + data)
Error:
http://0.0.0.0:8080/
127.0.0.1:64395 - - [06/Sep/2019 00:19:16] "HTTP/1.1 GET /post" - 405
Method Not Allowed

You're mixing GET and POST.
The Error indicates you're doing a "GET" operation, on the url '/post'.
web.py takes the URL and looks it up in the urls list, and identifies the url '/post' is handled by the class "PostRegistration".
So, web.py calls the GET method on class PostRegistration, which doesn't exist, or, as web.py says "Method Not Allowed".
To get past that, either use a POST operation (as #Barmar suggests) or, rename PostRegistration.POST(self) to PostRegistration.GET(self).

Related

POST request to Flask Blueprint api not working

I am trying to execute a form POST request. The request is received at the route api function but the POST condition is not executing.
Code
<form class="pt-2 pb-4" action = "{{ url_for('data_sources_api.testfn') }}" method = "POST">
<div class="row">
<div class="col-md-4 mb-3">
<label for="url" class="form-label">URL</label>
<input type="text" class="form-control" id="url" name="url" aria-describedby="emailHeurllp"
placeholder="Enter new events top domain source url">
</div>
<div class="col-md-4 mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Enter Organization Name">
</div>
<div class="col-md-12">
<button type="button" class="btn btn-secondary mr-2" value="submit" name = "submit">Submit</button>
</div>
</div>
</form>
Flask Code
#data_sources_api.route('/login/test', methods=["GET", "POST"])
def testfn():
# Check if user is loggedin
if loggedin():
# User is loggedin, render the home page
if request.method == 'POST':
print("POST Request Received")
result = request.form
return render_template('users/data-sources.html', role=session['role'])
return redirect(url_for('account_api.login'))
The request received is GET when i click the submit button and not POST :(
Thanks in advance
I think the problem is with button. Replace the button with input type="submit":
<input type="submit" value="Submit">
Here is the example of Django form.

Update the password if the user has forgotten while Login-in, Python Flask

I am trying to update the password if the user has forgotten while Login-in. But continuously it is giving the same error given below.
Bad Request: The browser (or proxy) sent a request that this server could not understand.
app.py
#app.route('/NewPassword', methods=['POST', 'GET'])
def NewPassword():
if request.method == 'POST':
OldEmail = request.form['NewPswdInputEmail']
OldPhone = request.form['NewPswdInputPhoneNo']
NewPaswd = request.form['NewPaswdInputPassword']
cur = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cur.execute("UPDATE USERS SET Paswd='" + NewPaswd + "' WHERE Email ='" + OldEmail + "' OR Phone ='" + OldPhone + "'")
cur.connection.commit()
return "Password Updated"
return render_template('NewPassword.html')
NewPassword.html
<form action="/NewPassword" method="post" oninput='NewPaswdConPassword.setCustomValidity(NewPaswdConPassword.value != NewPaswdInputPassword.value ? "Password does not match." : "")'>
<div class="form-group">
<label for="customRadio">Select Option to Change Password Between Email & Phone No.</label>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="customRadioInline1" name="customRadioInline" value="Email" class="custom-control-input" checked>
<label class="custom-control-label" for="customRadioInline1">Email Id</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="customRadioInline2" name="customRadioInline" value="Phone" class="custom-control-input">
<label class="custom-control-label" for="customRadioInline2">Phone No.</label>
</div>
</div>
<div class="form-group" id="EmailShowHide">
<label for="NewPswdInputEmail">Email Address</label>
<input type="email" class="form-control" name="loginInputEmail" id="NewPswdInputEmail" aria-describedby="emailHelp" placeholder="Email address">
<small id="loginemailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group" id="PhoneShowHide" style="display: none">
<label for="NewPswdInputPhoneNo">Phone Number</label>
<input type="tel" id="NewPswdInputPhoneNo" name="NewPswdInputPhoneNo" class="form-control" pattern="[0-9]{4}[0-9]{2}[0-9]{4}" placeholder="Phone number">
<small id="NewPswdPhoneHelpInline" class="text-muted">Enter Valid Number</small>
</div>
<div class="form-group">
<div class="tool">
<label for="NewPaswdInputPassword">New Password</label>
<div class="input-group" id="NewPaswdShowHide">
<input type="password" class="form-control" name="NewPaswdInputPassword" id="NewPaswdInputPassword" pattern="^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9]).{8,20}$" placeholder="New password" required>
<div class="input-group-append">
<a class="btn btn-primary">
<i class="bi bi-eye-slash" aria-hidden="true"></i>
</a>
</div>
</div>
<span class="tooltext">Password Must be Alphanumeric with atleast an UpperCase & LowerCase Characters</span>
<small id="NewPaswdHelpInline" class="text-muted">Must be 8-20 characters long.</small>
</div>
</div>
<div class="form-group">
<label for="NewPaswdInputConPassword">Confirm New Password</label>
<input type="password" class="form-control" name="NewPaswdConPassword" id="NewPaswdInputConPassword" placeholder="Confirm new password" required>
</div>
<button type="submit" name="Login" id="NewPaswdSubmit" class="btn btn-primary">Submit</button>
</form>
I am trying to do is, if my database "USERS" has Email or Phone no. then Paswd will get updated with the new password which is input by the user
Please tell me what I am doing wrong.
I assume you are using Flask. Is your application running in debug mode?
Running the application in debug mode can help identify where the issue is.
The issue is with the email HTML form input. When you submit a form, the data is sent as key=value pairs, in this case you are using Flask so it is a python dictionary. So in the /NewPassword route, when you request request.form['NewPswdInputEmail'], you are grabbing a value in that dictionary submitted from the form with 'NewPswdInputEmail' as a key.
In the form input the key is the name attribute.
That's why you get the KeyError because the name in the email input form has name="loginInputEmail" instead of name="NewPswdInputEmail"
All you need to do is rename loginInputEmail attribute in the email input field to NewPswdInputEmail.

Problem in getting data from form in flask

I am basically creating a flask web app which takes username from user and gets his /her codeforces data I am having a problem in extracting the email-id
from the form. I am getting the username but not the email-id.They are both in one form tag in the html file.
Error in browser:
werkzeug.exceptions.HTTPException.wrap..newcls: 400 Bad Request: KeyError: 'email-id'
<form method="POST">
<div class="field">
<label class="label">Username:</label>
<div class="control">
<input class="input" type="text" placeholder="Enter Codeforces username" name="username" value="{{user.handle}}"></input>
</div>
</div>
<div class="has-text-centered">
<input class="button is-link" name="get-info" type="submit" value="Get Info">
</div>
<div class="field">
<label class="label">EMail id:</label>
<div class="control">
<input class="input" type="text" placeholder="Enter mail id" name="email-id" value="">
</div>
</div>
<div class="has-text-centered">
<input class="button is-link" name="get-mail" type="submit" value="Get Mail">
</div>
</form>
#app.route('/',methods=['GET','POST'])
def index():
if request.method == 'POST':
username = request.form['username']
email_id = request.form['email-id']
print(email_id)
print(username)

How to post data via form HTML?

I want to post the data to the server via form. How can I do this?
<div class="panel-body">
<form role="form" action="{% url 'login' %}" method="POST">
{% csrf_token %}
<div class="form-group">
<label for="sender-email" class="control-label">Username:</label>
<div class="input-icon"> <i class="icon-user fa"></i>
<input id="sender-email" type="text" placeholder="Username" class="form-control email">
</div>
</div>
<div class="form-group">
<label for="user-pass" class="control-label">Password:</label>
<div class="input-icon"> <i class="icon-lock fa"></i>
<input type="password" class="form-control" placeholder="Password" id="user-pass">
</div>
</div>
<div class="form-group">
<input class="btn btn-primary btn-block" id="authenticate_user" type="submit" value="Submit">
</div>
</form>
</div>
My views.py
#csrf_exempt
def signin(request):
if request.method == 'POST':
print request.POST.get('sender-email') #prints None
username = request.POST['username'] # throws error, username not available.
password = request.POST['password']
How do I post the data without using jquery? I know of a way of posting through AJAX jquery, but dont wanna do that.
The 'name' attribute of input tags is set as keys of request.GET and request.POST.
Add name attribute to all your input tags.
<input name="username" id="sender-email" type="text" placeholder="Username" class="form-control email">
<input name="password" type="password" class="form-control" placeholder="Password" id="user-pass" >
POST data are populated using the name attribute of your input elements. Change your id attributes or add a name one accordingly. E.g:
<input type="password" class="form-control" placeholder="Password" name="user-pass">
You should also consider using a form to handle your data more easily.

Flask MethodView No request object in def Post(self)

I am trying to send a html5 form to flask using the class based MethodView. From what I understand, the def post(self): should contain a request object with the form attributes. However, when I try the below code I get "NameError: global name 'request' is not defined"
flask:
from app import app
from flask.views import MethodView
from app import app
from flask.views import MethodView
from flask import url_for
#app.route('/')
def index():
return app.send_static_file('index.html')
class ImageShareForm(MethodView):
def get(self):
pass
def post(self):
print (request)
app.add_url_rule('/imageshareform/', view_func=ImageShareForm.as_view('imageshareform'))
html:
<form method="POST">
<div class="form-group btn-group-ls well col-md-5">
<legend>Region</legend>
<input class="form-inline" type="radio" name="regions" id="IAD" value="IAD" checked>
<label for="IAD" class="btn btn-default region">Virginia</label>
<input class="form-inline" type="radio" name="regions" id="ORD" value="ORD">
<label for="ORD" class="btn btn-default region">Chicago</label>
<input class="form-inline" type="radio" name="regions" id="DFW" value="DFW">
<label for="DFW" class="btn btn-default region">Dallas</label>
<input type="radio" id="HKG" name="regions" value="HKG">
<label for="HKG" class="btn btn-default region">Hong Kong</label>
</div>
<div class="form-group well col-md-5">
<label for="producerUsername">Producer Username</label>
<input type="text" class="form-control" id="producerUsername" placeholder="Enter producer's username" >
<label for="producerApiKey">Producer Api Key</label>
<input type="text" class="form-control" id="producerApiKey" placeholder="Enter producer's api key" >
</div>
<div class="form-group well col-md-5">
<label for="consumerUsername">Consumer Username</label>
<input type="text" class="form-control" id="consumerUsername" placeholder="Enter consumer's username" >
<label for="consumerApiKey">Consumer Api Key</label>
<input type="text" class="form-control" id="consumerApiKey" placeholder="Enter consumer's api key" >
</div>
<div class="form-group well col-md-5">
<label for="imageUuid">Image UUID</label>
<input type="text" class="form-control" id="imageUuid" placeholder="Enter images's image Uuid" >
</div>
<div class="col-md-5">
<input type="submit" value="Submit" class="btn btn-primary" formenctype="multipart/form-data" formaction="/imageshareform">
</div>
</form>
Found out I needed to import request that comes with Flask

Categories