I'm trying to complete a forex money converter in FLASK but my code isn't working.
It allows the user input, then once I hit submit the next page that shows Method Not Allowed
The method is not allowed for the requested URL.
-Update, now it just goes to an action page, whenever I try to pull up the Index2.html it doesn't load. I'm not sure why its not allowing me to proceed.
-I'm trying to save three inputs, add them to a list, then convert them into a dollar amount
-Page Refreshes to action page, this is not what is intended
Index.html file
><!DOCTYPE html>
<html>
<body>
<h2>HTML Forms</h2>
<form action="/index2.html", method="Post">
<label for="C1" name= "C1"> Converting From:</label><br>
<input type="text" id="C1" name="C1"><br>
<label for="C2">Converting To:</label><br>
<input type="text" id="C2_to" name="C2_to"><br>
<label for="amt">Amount:</label><br>
<input type="text" id="amt" name="amt"><br>
<br>
<input type="submit" value="Submit">
</form>
app.py file
from flask import Flask, render_template,request, redirect, session
from forex_python.converter import CurrencyCodes, CurrencyRates
app = Flask(__name__)
app.config["secret key"]="yeah"
app.config['DEBUG_TB_INTERCEPT_REDIRECTS'] = False
responses_key= "responses"
#app.route("/")
def show_form():
return render_template("Index.html" )
#app.route("/index2")
def show_form2():
return render_template("index2.html" )
T= CurrencyRates()
#app.route("/Index2", methods=["POST"])
def save_answer():
line2 = request.data.get("C1", "C2", int("amt"))
responses = session[responses_key]
responses.append(line2)
responses = session[responses]
rate = T.convert(line2[0],line2[1],int(line2[2]))
return rate,render_template("/Index2.html", rate="response")
As index2.htlm is not shared, i created a simple 1 liner index2.html to show the conversion. PFB code:
app.py:
from flask import Flask, render_template, request, redirect, session, url_for
from forex_python.converter import CurrencyCodes, CurrencyRates
app = Flask(__name__)
app.config["secret key"] = "yeah"
app.config['DEBUG_TB_INTERCEPT_REDIRECTS'] = False
responses_key = "responses"
#app.route('/', methods = ['GET', 'POST'])
def index():
return render_template('Index.html')
T = CurrencyRates()
#app.route("/conversion", methods = ['GET', 'POST'])
def conversion():
if request.method == 'POST':
C1 = request.form.get('C1', None)
C2_to = request.form.get('C2_to', None)
amt = request.form.get('amt', None)
rate = T.convert(C1, C2_to, int(amt))
print(C1, C2_to, amt, rate)
details = {'C1': C1, 'C2_to': C2_to, 'amt': amt, 'rate': rate}
return render_template("Index2.html", details=details)
if __name__ == '__main__':
app.run(host='xx.xx.xx.xx', debug=True)
app.run(debug=True)
Index.html:
<!DOCTYPE html>
<html>
<body>
<h2>HTML Forms</h2>
<form action="{{ url_for('conversion') }}" method="post">
<label for="C1" name= "C1"> Converting From:</label><br>
<input type="text" id="C1" name="C1"><br>
<label for="C2_to" name= "C2_to">Converting To:</label><br>
<input type="text" id="C2_to" name="C2_to"><br>
<label for="amt">Amount:</label><br>
<input type="text" id="amt" name="amt"><br>
<br>
<input type="submit" value="Submit">
</form>
Index2.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<p> Conversion of {{ details.amt }} {{ details.C1 }} to {{ details.C2_to }} is: {{ details.rate }}</p>
</body>
</html>
Output:
homepage:
conversion page:
Related
I am currently developping an application on django and when i send a post request from a form, is_valid method return false, but form.is_bound return True.
my form.error -> mailThis field is required.prenomThis field is required.nomThis field is required.
my forms.py
from django import forms
class formadduser(forms.Form):
mail = forms.CharField(label='Mail', max_length=40)
# imput_username = forms.CharField(input='input_username', max_length=100)
prenom = forms.CharField(label='Prénom', max_length=25)
# input_password = forms.CharField(input='input_pathword', max_length=100)
nom = forms.CharField(label = 'Nom', max_length=25)
views.py where i'm trying to get the form inputs:
from re import S
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect, QueryDict
from .forms import formadduser
import pickle
import os
from .fonctions import tri
from .models import Users
# Create your views here.
def administrator(request) :
# test = request.POST[username]
# print(test)
# request.form['username'] je crois que c'est du flask
return render(request, 'admin.html')
def index(request):
if request.method == 'POST':
var = request.POST["username"]
print(var)
text = """<h1>{{var}}</h1>
<p>les crepes nananinanana</p>"""
return HttpResponse(text)
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = formadduser(request.POST)
print(form)
# check whether it's valid:
if form.is_valid():
print("debug")
print(form.cleaned_data["mail"])
var = Users(mail = form.cleaned_data["Mail"], prenom = form.cleaned_data["Prenom"], nom = form.cleaned_data["Nom"])
var.save()
# process the data in form.cleaned_data as required
# ...
# print(NameForm.username)
# redirect to a new URL:
# return HttpResponseRedirect('/thanks/')
# Username = form.cleaned_data
# text = """<h1>{{form.cleaned_data["username"]}}</h1>
# <p>les crepes nananinanana</p>"""
# return HttpResponse(text)
# print(form.cleaned_data["username"])
# u = USERS(Username = form.cleaned_data["username"], droits = form.cleaned_data["droits"])
# u.save()
# query = pickle.loads("zeubi")
# test = list(USERS.objects.values("Username"))
# test = USERS.objects.values("Username")
# test = USERS.objects.all()
# test = str(USERS.objects.values("droits"))
# res = tri(test)
# user_qs = USERS.objects.all()
# for user in user_qs:
# print(user['Username'])
# testv = QueryDict
# test.query = query
return render(request, 'admin.html')
# return render(request, 'admin.html', {'test' : test})
# return(locals())
# USERS.Username = form.cleaned_data["username"]
# return form.cleaned_data
else:
print("invalid form")
print(form.is_bound)
# print(form.errors)
# if a GET (or any other method) we'll create a blank form
else:
print("error")
form = formadduser()
return render(request, 'admin.html', {'form': form})
templates.py with 4 forms but my test is on formadduser:
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ADMIN</title>
{% load static %}
<script src="{% static 'global/jquery.js' %}"></script>
<script src="{% static 'administrator/admin.js' %}"></script>
<link rel="stylesheet" type="text/css" href="{% static 'administrator/admin.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'global/StyleGlobal.css' %}">
</head>
<body id="idbody" onclick="fout();foutform()">
<div class="bande">
<div onclick="testhb()" id="hb">
<div class="barre"></div>
<div class="barre"></div>
<div class="barre"></div>
<ul id="ulmenu">
<li class="menu"><a class="textdeco" href="http://10.75.101.201/Front/mat/mat.html">Materiel</a></li>
<li class="menu"><a class="textdeco" href="http://10.75.101.201/Front/offrecgr/offrecgr.html">Offres/CGR</a></li>
</ul>
</div>
<!-- </div> -->
<div class="logo">
<img src="{% static 'global/GHD.png' %}" alt="Logo">
<!-- -->
</div>
</div>
<div class="titre">
<h1 class="accueiltxt">ADMIN</h1>
</div>
<div class="gigacontainer" id="gigacontainer">
<div class="containerbutton">
<div class="button" id="buttonsuppuser" onclick = "buttonsuppuser()">
<p class="trashcan">🗑</p></div>
<div class="button" id="buttonadduser" onclick="buttonadduser()">+</div>
<div class="txtbutton">Users</div>
<div class="button" id="buttonsuppapp" onclick = "buttonsuppapp()">🗑</div>
<div class="button" id="buttonaddapp" onclick = "buttonaddapp()">+ </div>
<div class="txtbutton">Apps</div>
</div>
<form action="" method="post" class="form" id="formsuppuser">
{% csrf_token %}
<label for="suppuser">Username</label>
<input type="text" name="suppuser" id="suppuser">
<button>Supprimer</button>
</form>
<form name="formadduser" action="" method="post" class="form" id="formadduser">
{% csrf_token %}
<label for="addusermail">Mail</label>
<input required="required" type="text" name="addusermail" id="addusermail">
<label for="adduserprenom">Prénom</label>
<input required="required" type="text" name="adduserprenom" id="adduserprenom">
<label for="addusernom">Nom</label>
<input required="required" type="text" name="addusernom" id="addusernom">
<button type="submit">Ajouter</button>
</form>
<form action="" method="post" class="form" id="formsuppapp">
{% csrf_token %}
<label for="suppapp">Application</label>
<input type="text" name="suppapp" id="suppapp">
<button>Supprimer</button>
</form>
<form action="" method="post" class="form" id="formaddapp">
{% csrf_token %}
<label for="addapp">Application</label>
<input type="text" name="addapp" id="addapp">
<button>Ajouter</button>
</form>
</div>
</html>
You should have the errors in form.errors, without them, we cannot tell you anything.
It may also be that your form is not bound (request data have not be sent to the form). You can check this with form.is_bound.
If this return false, you did not send your data into your form:
form = MyForm(data=request.POST)
You can see how is_valid works in the django source.
As you can see, you can know whats wrong juste by checking form.is_bound or form.errors.
I have a python script and a mongoDB instance.
With flask I now want to list all the items of my database on a webpage and use a second webpage to trigger the script to add an other item.
But everytime I click "submit" on the "/add" page, I get a "Method not allowed" and I can see, that it tries to submit it to "/" instead of "/add" ..
script.py
from flask import Flask, render_template, request
import requests, json, sys, getopt, smtplib
from os import system, name
from pathlib import Path
from pymongo import MongoClient
client = MongoClient(port = 27017)
db = client.amazonProducts
allitems = []
allMyItems = []
for document in db.items.find():
allitems.append(document["name"])
def addItem():
for dbWishList in db.wishlist.find():
url = dbWishList["wishlist"]
items = json.loads(requests.get(url).text)
if items:
for item in items:
itemName = str(item["name"])
itemPrice = item["new-price"]
itemUrl = str(item['link'])
if itemPrice:
itemPrice = str(itemPrice[26: ])
itemPrice = str(itemPrice[: itemPrice.find("<")])
itemPriceF = str(itemPrice.replace(".", ""))
itemPriceF = str(itemPriceF.replace("€", ""))
itemPriceF = str(itemPriceF.replace("\xa0", ""))
itemPriceF = str(itemPriceF.replace(",", ".")).replace("\xf6", "")
itemPriceFi = float(itemPriceF)
itemUrl = itemUrl[: itemUrl.find("?coliid")]
itemNameF = itemName.replace('"', '"')
itemNameFi = itemNameF.replace("&", "&")
itemNameFi = itemNameFi.replace("ü", "ue").replace("ö", "oe").replace("ä", "ae").replace(" ", " ").replace("–", "-")
amazonItem = {
'name': itemNameFi,
'url': itemUrl,
'price': itemPriceFi,
'maxPrice': 0
}
db.items.insert_one(amazonItem)
for document in db.items.find():
allMyItems.append(document["name"])
return allMyItems
app = Flask(__name__)
#app.route('/')
def homepage():
return render_template("index.html", len = len(allitems), allitems = allitems)
app.run(use_reloader = True, debug = True)
app.config["DEBUG"] = True
#app.route("/add", methods = ["GET", "POST"])
def secPage():
errors = ""
if request.method == "POST":
global testingVar
testingVar = None
try:
testingVar = string(request.form["testingVar"])
except:
errors += "<p>{!r} is not a string.</p>\n".format(request.form["testingVar"])
if testingVar is not None:
addItem()
return render_template("secIndex.html", len = len(allMyItems), allMyItems = allMyItems)
return '''
<html>
<body>
{errors}
<p>What you wanna do?:</p>
<form method="post" action=".">
<p><input name="testingVar" /></p>
<p><input type="submit" value="Do magic" /></p>
</form>
</body>
</html>
'''.format(errors=errors)
index.html
<!DOCTYPE html>
<html>
<head>
<title>For loop in Flask</title>
</head>
<body>
<ul>
<!-- For loop logic of jinja template -->
{%for i in range(0, len)%}
<li>{{allitems[i]}}</li>
{%endfor%}
</ul>
</body>
</html>
secIndex.html
<!DOCTYPE html>
<html>
<head>
<title>For loop in Flask</title>
</head>
<body>
<!-- For loop logic of jinja template -->
<form method="post" action=".">
<p><input name="testingVar" /></p>
<p><input type="submit" value="Do magic" /></p>
</form>
</body>
</html>
The items are built like:
amazonItem = {
'name': itemNameFi,
'url': itemUrl,
'price': itemPriceFi,
'maxPrice': 0
}
Can anyone here follow me and tell me where my mistake might be?
In your form definition you have:
<form method="post" action=".">
The action attribute needs to have the endpoint you want to send the post request to. In your case, you want
<form method="post" action="/add">
If you omit the action attribute, it will submit the post request to the current page, so if you are viewing your form from /add, you can just use
<form method="post">
My Flask app does calculations based on user form inputs. These calculation take about 10 seconds to complete. The output of those calculations need to be displayed in a div on the same page, next to the form (in a chart / table etc).
I have tried two aproaches. The first, using normal just Flask, reloads the whole page, which is far from ideal. The second approach, using Sijax, updates just the div. But in this case, i don't know how to access the form inputs.
I'm confused how to get this working. Would appreciate any directions!
Approach 1: just flask (downside: whole page reloads)
form_test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Testpage</title>
</head>
<body>
<form action="{{ url_for('do_the_math') }}" method="post">
A = <input type="number" name="input_A">
B = <input type="number" name="input_B">
<input type="submit" value="Submit">
</form>
<div id="destination_div">A + B = {{ result }}</div>
</body>
</html>
app_normal.py:
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route("/")
def show_home():
return render_template("form_test.html", result='unknown yet')
#app.route("/do_the_math", methods=['POST'])
def do_the_math():
A = request.form.get('input_A')
B = request.form.get('input_B')
sum = float(A) + float(B)
# reloads whole page
return render_template("form_test.html", result=sum)
# what i want: reload just update destination_div with new HTML
# return render_template("#destination_div", "A + B = " + str(sum))
if __name__ == '__main__':
app.run(debug=True)
Approach 2: use Sijax (updates div, but how to access form inputs?)
form_test_sijax.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Testpage with sijax</title>
<script type="text/javascript" src="/static/js/sijax/sijax.js"></script>
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
</head>
<body>
<form method="post">
A = <input type="number" name="input_A">
B = <input type="number" name="input_B">
<button type="button" onclick="Sijax.request('submit_form');">calc</button>
</form>
<div id="destination_div">A + B = unknown</div>
</body>
</html>
app_sijax.py
from flask import Flask, render_template, g
import flask_sijax
import os
app = Flask(__name__)
# init sijax
app.config["SIJAX_STATIC_PATH"] = os.path.join('.', os.path.dirname(__file__), 'static/js/sijax/')
app.config["SIJAX_JSON_URI"] = '/static/js/sijax/json2.js'
flask_sijax.Sijax(app)
def submit_form_handler(obj_response):
A = 5 # how do get to the values entered in the form?
B = 3
sum = A + B
obj_response.html("#destination_div", "A + B = " + str(sum))
#flask_sijax.route(app, "/")
def show_home():
result = 'unknown'
if g.sijax.is_sijax_request:
g.sijax.register_callback('submit_form', submit_form_handler)
return g.sijax.process_request()
return render_template("form_test_sijax.html")
if __name__ == '__main__':
app.run(debug=True)
You can use ajax with jquery to dynamically update the page with the computed result without having to refresh the page:
In the html file:
<html>
<header>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</header>
<body>
<div class='wrapper'>
A = <input type="number" id="input_A">
B = <input type="number" id="input_B">
<button class='get_result'>Calculate</button>
<div class='result'></div>
</div>
</body>
<script>
$(document).ready(function(){
$('.wrapper').on('click', '.get_result', function(){
var val1 = $("#input_A").val();
var val2 = $("#input_B").val();
$.ajax({
url: "/calculate_result",
type: "get",
data: {val1: val1, val2:val2},
success: function(response) {
$(".result").html('<p>'+response.result.toString()+'</p>');
},
});
});
});
</script>
</html>
Then, in the main app file, create the route to calculate the final result:
#app.route('/calculate_result')
def calculate_result():
a = int(flask.request.args.get('val1'))
b = int(flask.request.args.get('val2'))
return flask.jsonify({"result":a+b})
My form submits data through a sijax request and to acknowledge the submission I use obj_response. I tried both obj_response.alert() as well as obj_response.html() but nothing worked
My code:
from flask import Flask, render_template, request, flash, g, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
import flask_sijax
import os
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///Login.sqlite3"
path = os.path.join('.', os.path.dirname(__file__), 'static/js/sijax1/')
app.secret_key = 'super secret key'
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SIJAX_STATIC_PATH'] = path
app.config['SIJAX_JSON_URI'] = 'static/js/sijax/json2.js'
db = SQLAlchemy(app)
flask_sijax.Sijax(app)
class Signup(db.Model):
ID = db.Column("ID", db.String(10), primary_key=True)
Fname = db.Column(db.String(20))
LName = db.Column(db.String(20))
Password = db.Column(db.String(20))
def __init__(self, id, fname, lname, password):
self.ID = id
self.Fname = fname
self.LName = lname
self.Password = password
#flask_sijax.route(app, '/signup')
def home():
def caller(obj_response, values):
newuser = Signup(values['ID'], values['fname'], values['lname'], values['Password'])
db.session.add(newuser)
db.session.commit()
obj_response.html("#result", "Successfully signed up")
if g.sijax.is_sijax_request:
g.sijax.register_callback('call', caller)
return g.sijax.process_request()
return render_template("first.html")
#app.route("/success", methods=['POST', 'GET'])
def success():
records = db.session.query(Signup).all()
return render_template("second.html", records=records)
if __name__ == "__main__":
db.create_all()
app.run(host="127.0.0.1", port=2908, debug=True, threaded=True)
My HTML file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sign Up</title>
<script type="text/javascript" src="{{url_for('static',filename='Signup.js')}}"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script type="text/javascript" src="{{url_for('static', filename='js/sijax/sijax.js')}}"></script>
<script type="text/javascript">{ {g.sijax.get_js()|safe }}</script>
<link rel="stylesheet" href="{{url_for('static', filename='styles/firstcss.css')}}">
</head>
<body style = "font-family: Lato">
<div style="padding-left: 5%;padding-top:0.2%;padding-bottom: 0px;height: 4%;width: 100%;background-color: #11557C;margin-left: 0px;margin-top: 0px;">
<h2>Welcome to my site</h2><br>
</div>
<div style="margin-left: 70%" width="100%">
<form method="post" action="http://127.0.0.1:2908/success">
<input type="submit" style="position: relative;margin-top: 5%;margin-left:20%" value="View Logs">
</form>
</div>
<div style="width:80%">
<form name="form1" id="form1" method="post" style="padding-top: 1%"><!--action = "http://127.0.0.1:2908/success"!-->
<label id="head" style="font-size: 20px;padding-bottom: 1%;">Sign Up</label><br>
<label id="user" style="font-size: 16px;margin-top: 5%;">Username</label><br>
<input type="text" name = "ID" placeholder = "Username" style = "padding-left: 0.2%;"><br><br>
<label style="font-size: 16px">First name</label><br>
<input type="text" name = "fname" id="fname" placeholder = "First name" style = "padding-left: 0.2%"><br><br>
<label style="font-size: 16px">Last name</label><br>
<input type="text" name = "lname" placeholder = "Last name" style = "padding-left: 0.2%"><br><br>
<label style="font-size: 16px">Password</label><br>
<input type = "password" name = "Password" placeholder = "Password" style = "padding-left: 0.2%"><br><br><br>
<input type = "submit" onclick="return validate()" value = "Sign up" style="width:50%;height: 40px;margin-left: 12%;background-color: #11557C;color: black">
</form>
</div>
<h3 id="result" >RESULT</h3>
</body>
</html>
I noticed Sijax stopped working when using a jQuery version higher then 1.5.1
So try replacing:
https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js
With:
https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js
But I did not find any other confirmation from other developers or forums on this point, just my own.
I am using flask web server and want to do the following functionality.
Pass form data from home.html to python func plot_perf_metric().
Save form data and call plot.html.
plot.html calls output_plot() which generates a plot based on the saved form data and accessing values from a database(mongodb).
plot.html prints this plot.
I am currently not getting the image displayed.
I only get a broken link of the image.
Can someone help me?
home.html
<!DOCTYPE html>
<html lang="en">
<body>
<form action="./plot" method="POST">
<input type="radio" name="perf_metric" value="disk"> Disk <br><br>
<input type="radio" name="perf_metric" value="memory"> Memory <br><br>
<input type="radio" name="perf_metric" value="cpu"> CPU <br><br>
<input type="radio" name="perf_metric" value="egress"> Egress <br><br>
<input type="radio" name="perf_metric" value="flit"> Flit <br><br>
<input type="submit" name="submit_plot" value="Send">
</form>
</body>
</html>
routes.py
from flask import Flask, render_template, send_file
from flask import request,make_response
from pymongo import MongoClient
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
import StringIO
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
import random
app = Flask(__name__)
#app.route('/')
def home():
return render_template('home.html')
def connect_mongo(text):
client = MongoClient()
db = client['mydb']
collection = db['vload']
b = list()
a = list(collection.find())
for i in range(len(a)):
b.append(a[i][text])
return b
#app.route('/output')
def output_plot():
fig = Figure()
axis = fig.add_subplot(1, 1, 1)
b=connect_mongo(plot_perf_metric.text)
fig = axis.plot(b)
output = StringIO.StringIO()
response = make_response(output.getvaluest())
response.mimetype = 'image/png'
fig.savefig(output)
output.seek(0)
return send_file(output, mimetype='image/png')
#app.route('/plot',methods=['POST'])
def plot_perf_metric():
if(request.form['submit_plot'] == "Send"):
text = request.form['perf_metric']
return render_template('plot.html')
if __name__ == '__main__':
app.run(debug=True)
plot.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Plot</title>
</head>
<body>
<img src="{{ url_for('output_plot') }}" alt="Image Placeholder" height="100">
</body>
</html>
You need to add a route for output_plot.
#app.route('/output')
def output_plot():
fig = Figure()
axis = fig.add_subplot(1, 1, 1)
b=connect_mongo(plot_perf_metric.text)
fig = axis.plot(b)
output = StringIO.StringIO()
response = make_response(output.getvaluest())
response.mimetype = 'image/png'
fig.savefig(output)
output.seek(0)
return send_file(output, mimetype='image/png')