Python global variable not updating in real time flask - python

value=user_id is not taking the new value defined by def login():.for e.g. if the entered user_id from HTML page is 200, 300 and 100. The values will be assigned as 0, 200, 300. That is, when home page is displayed it will be showing user 0 for entered value 200, and for second time it is showing 200 for entered value 300 and for third time it is showing 300 for entered value 100.
I need a real time values i.e. for entered value 200 home page should have value 200, and for 300 it should be 300. Could anyone please help me with this? Please advice. Thanks in advance. Note: HTML code is not optimized.
from flask import Flask, render_template # Flask is the class within the flask library
from flask import request, redirect
user_id = int(0)
app = Flask(__name__) # Instance of the object Flask. __name__: this gets value of name of python script
#app.route('/', methods=["GET", "POST"]) # login page
def login():
if request.method == "POST":
global user_id
user_id = request.form['userid']
print(user_id)
return render_template("login.html")
#app.route('/home/') # This the URL i.e. home page
def home():
return render_template("home.html", value=user_id)
if __name__ == "__main__":
app.run(debug=True)
HTML Code for Login page here.
<!DOCTYPE html>
<html>
<head>
<title>Recommender System App</title>
<link rel="stylesheet" type="text/css" href="{{url_for('static',filename='css/main.css')}}">
</head>
<body>
<header>
<div class="container">
<h1 class="logo">Movie Recommender System</h1>
<strong><nav>
<ul class="menu">
</ul>
</nav></strong>
</div>
</header>
<form action="{{ url_for('login') }}" method="post">
<div class = "Login Fields">
<b>Username:</b> <input type="number" placeholder="Numbers only" name='userid'>
<p><b>Password:</b> <input type="password" placeholder="Enter Password" name= 'password' id="pwd"></p>
<input type="submit" onclick="check(this.form)" class="button">
</div>
<p></p>
<p></p>
<div>
<p>Test User IDs:</p>
<li>224</li>
<li>216</li>
<li>681</li>
<li>19</li>
<li>82</li>
<li>305</li>
<li>44</li>
<li>268</li>
<p>Password: 123Swaroop</p>
</div>
</form>
<script language="javascript">
function check(form)/*function to check userid & password*/
{
if(form.password.value == "123Swaroop")
{
window.open(href = "{{ url_for('home') }}")
}
else
{
alert("Wrong Password or User Id")/*displays error message*/
}
}
</script>
</body>
</html>
HTML code for home page here:
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
<link rel="stylesheet" type="text/css" href="{{url_for('static',filename='css/main.css')}}">
</head>
<body>
<header>
<div class="container">
<h1 class="logo">Welcome User: {{ value }}</h1>
<strong><nav>
<ul class="menu">
</ul>
</nav></strong>
</div>
</header>
<div class = "home">
<h1>Top Rated Movies</h1>
<p>This is test website</p>
</div>
</body>
</html>

You also need to call the global value within your home() function:
from flask import Flask, render_template, request, redirect
user_id = int(0)
app = Flask(__name__)
#app.route('/', methods=["GET", "POST"])
def login():
if request.method == "POST":
global user_id
user_id = request.form['userid']
print(user_id)
return render_template("login.html")
#app.route('/home/')
def home():
global user_id
return render_template("home.html", value=user_id)
if __name__ == "__main__":
app.run(debug=True)
However, using global variables is usually considered bad practice so you could also consider something like this:
from flask import Flask, render_template, request, redirect
app = Flask(__name__)
#app.route('/', methods=["GET", "POST"])
def login():
return render_template("login.html")
def get_user_id():
try:
if request.method == "POST":
user_id = request.form['userid']
return user_id
else:
# Handle error or do something else
except:
# Handle error or do something else
#app.route('/home/')
def home():
try:
return render_template("home.html", value=get_user_id())
except:
# Handle error or do something else
if __name__ == "__main__":
app.run(debug=True)

Related

python flask session , login and index not working

I have a python flask app with login module implemented using extension python flask. In my login method.
The Error Message
app.py
# import the Flask class from the flask module
from flask import Flask, render_template, redirect, url_for, request, session
# create the application object
app = Flask(__name__)
app.secret_key = "hello"
# use decorators to link the function to a url
##app.route('/')
#def home():
# return "Hello, World!" # return a string
#app.route('/index', methods=['GET'])
def index():
if session.get ('username'):
return render_template('index.html')
else:
return render_template('login.html') # render a template
# route for handling the login page logic
#app.route('/', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or request.form['password'] != 'admin':
error = 'Invalid Credentials. Please try again.'
else:
session['username'] = True
return redirect(url_for('index'))
return render_template('login.html', error=error)
# start the server with the 'run()' method
if __name__ == '__main__':
app.run(debug=True)
login page
login.html
<html>
<head>
<title>Flask Intro - login page</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="container">
<h1>Please login</h1>
<br>
<form action="" method="post">
<input type="text" placeholder="Username" name="username" value="{{
request.form.username }}">
<input type="password" placeholder="Password" name="password" value="{{
request.form.password }}">
<input class="btn btn-default" type="submit" value="Login">
</form>
{% if error %}
<p class="error"><strong>Error:</strong> {{ error }}</p>
{% endif %}
</div>
</body>
</html>
index.html
<DOCTYPE Html>
<html>
<head>
<tile>Addressing a Site</tile>
</head>
<body>
<address>welcome.</address>
</body>
</html>
i am trying to create a session between login and index page,just getting started with python flask framework, login session not working well.
It seems like you are actually having an issue with the methods rather than the session not working.
The Method Not Allowed error means that you are sending a GET/POST request to a page that does not accept that type of request.
Try changing the start of your login form to this
<form action="{{ url_for('login') }}" method="POST">
I just got it running on my computer and this works, the reason it did not work before was because the form was sending the post request to the /index route, which only accepts GET request.
Also, I noticed something else you may want to change.
You currently have this on your index route
if session.get ('username'):
return render_template('index.html')
else:
return render_template('login.html')
But it would be better to change that to this
if session.get ('username'):
return render_template('index.html')
else:
return redirect(url_for('login'))
That way the user is sent back to the login page rather than just being shown the login template from the index page.
I hope all of that helps.

Request form leads to error 405 Method Not Allowed in Flask

I am trying to set up a flask app which logs the user in and then prompts them with the segmentation page. The text box has then to be filled in by the user and upon submitting it, the text gets processed. Finally, the user should be logged out automatically.
However, I get a '405 Method Not Allowed' error when reaching the segmentation page.
from flask import Flask, jsonify, redirect, render_template, request, Response, session, url_for
app = Flask(__name__)
app.secret_key = 'super secret key'
#app.route('/')
def home():
"""
Sets up home page.
"""
return redirect(url_for('login'))
#app.route("/login", methods = ['POST', 'GET'])
def login():
"""
Login page to retrieve
"""
if request.method == 'POST':
user = request.form['nm']
session['user'] = user
return redirect(url_for("my_form_post"))
else:
if 'user' in session:
return redirect(url_for('my_form_post'))
return render_template('login.html')
#app.route('/segmentation')
def my_form_post(methods = ['GET','POST']):
"""
Sets up input text box and executes relevant action.
"""
if 'user' in session:
render_template('segment.html')
user = session['user']
if request.method == 'POST':
text = request.form['text']
# This function has no return argument
save_in_directory(text)
return redirect(url_for('logout'))
else:
return render_template('segment.html')
else:
return render_template('login.html')
#app.route("/logout")
def logout():
session.pop('user', None)
return redirect(url_for('submitted'))
#app.route("/sent")
def submitted():
return render_template('success.html')
if __name__ == '__main__':
app.run(debug = True)
The segment.html template is as follows:
{% extends "base.html"%}
{% block title%}Login Page{% endblock%}
{% block content%}
<body>
<p style="font-family: Helvetica; margin-left: 1.2em;"><b>Please, introduce the path:</b></p>
</body>
<form method="POST" style="font-family: Helvetica; font-style:italic; margin-left: 1.2em;" action="/segmentation">
<input name="text" size = 150>
<input type="submit">
</form>
<p style="font-size:1px;line-height:1;"><br/></p>
{% endblock %}
where base.html is:
<!doctype html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<link rel="shortcut icon" href="{{url_for('static', filename='heart.PNG')}}" type="image/png">
<img src="{{url_for('static', filename='welcome.png')}}" style='height: 100%; width: 100%; object-fit: cover'/>
{% block content%}
{% endblock %}
</html>
You're defining the methods for your /segmentation route as a function parameter which is incorrect, instead you have to define methods on route decorator like this:
#app.route('/segmentation', methods = ['GET','POST'])
def my_form_post():
...

How can I pass a value from a drop down list to another page in flask

I want to have a page where an option is selected from a drop down list that is passed to the next page. The error I receive is "UnboundLocalError: local variable 'currentuser' referenced before assignment". I'm not sure how to update the variable globally when an option is selected from the drop down list or how to access the global variable locally in the next page function. I am new to python and flask, any help would be greatly appreciated!
app.py
from flask import Flask, render_template
import sqlite3
app = Flask(__name__)
#app.route('/selectusername')
def selectusername_page():
# connect to database and populate userlist
conn = sqlite3.connect('users.db')
c = conn.cursor()
c.execute("SELECT * FROM users")
userlist = c.fetchall()
conn.close()
return render_template('selectusername.html', userlist=userlist)
#app.route('/showusername')
def showusername_page():
currentuser=currentuser
return render_template('showusername.html', currentuser=currentuser)
if __name__ == '__main__':
app.run(debug=True)
selectusername.html
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<body>
<button onclick="window.location.href = 'showusername';">Continue</button>
<h1>Select User</h1>
<select id="currentuser">
{% for user in userlist %}
<option value="{{user[0]}}">{{user[0]}}</option>
{% endfor %}
</select>
</body>
</html>
showusername.html
<h1>Hello {{ currentuser }}</h1>
If you use
<form action="/showusername">
and button without JavaScript and you use name="currentuser" in <select>
<select name="currentuser">
then it can send selected value in url
/showusername?currentuser=selected_name
and you can get it in showusername using request.args
currentuser = request.args.get("currentuser")
To hide name from url you would have to use POST method - so you have to set
<form action="/showusername" method="POST">
and in flask
#app.route('/showusername', methods=['POST', 'GET'])
and then you get it using request.form instead of request.args
currentuser = request.form.get("currentuser")
Full running example
from flask import Flask, render_template, render_template_string, request
app = Flask(__name__)
#app.route('/selectusername')
def selectusername_page():
userlist = [['James'], ['Adam'], ['Mark']]
return render_template_string('''<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<body>
<form action="/showusername">
<button>Continue</button>
<h1>Select User</h1>
<select id="currentuser" name="currentuser">
{% for user in userlist %}
<option value="{{user[0]}}">{{user[0]}}</option>
{% endfor %}
</select>
</form>
</body>
</html>''', userlist=userlist)
#app.route('/showusername', methods=['POST', 'GET'])
def showusername_page():
print('args:', request.args)
print('form:', request.form)
#currentuser = request.args.get("currentuser")
currentuser = request.form.get("currentuser")
return render_template_string('''<h1>Hello {{ currentuser }}</h1>''', currentuser=currentuser)
if __name__ == '__main__':
app.run(debug=True)
If you want to use JavaScript in button then you would have to use JavaScript to get selected value and add it to url like
window.location.href = 'showusername?currentuser=selected_name'
so it is more complicated and I don't put code in JavaScript. Maybe someone else will show this.

How to pass variables between HTML pages using Flask

I'm new to using Flask and I've just been trying to pass a variable between two web pages. The first is a simple form to accept a number with the second page just displaying what is entered.
HTML for the form page:
<!doctype html>
<html>
<body>
<form action ="{{ url_for('return_form', glon="glon") }}" method="post">
Galactic Longitude: <input type="text" name="glon">
<button type="submit">Submit</button>
</form>
</body>
</html>
HTML for the display page:
<!doctype html>
<body>
<p> {{ glon }} </p>
</body>
</html>
The Flask script currently looks like this:
from flask import Flask
from flask import render_template, url_for, request, redirect
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/form/', methods = ['GET', 'POST'])
def form():
if request.method == 'POST':
glon = request.form['glon']
#glat = request.form['glat']
return redirect(url_for('return_form', glon=glon))
return render_template('form.html')
#app.route('/return_form/<glon>', methods = ['GET', 'POST'])
def return_form(glon):
return render_template('return_form.html', glon=glon)
if __name__ == '__main__':
app.run()
At the moment, the second page just displays "glon" instead of the number passed to the form.
I simply want the variable to display on the second page, and eventually use it in the return_form function.
So i didn't got your approach.Below is what i did,I changed the code a bit. Hope this solves your problem.
main.py
from flask import Flask
from flask import render_template, url_for, request, redirect
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/form', methods = ['GET', 'POST'])
def form():
if request.method == 'POST':
glon = request.form['glon']
return render_template('display.html', glon=glon)
# #app.route('/return_form/<glon>', methods = ['GET', 'POST'])
# def return_form(glon):
# return render_template('return_form.html', glon=glon)
if __name__ == '__main__':
app.run()
index.html
<html>
<body>
<form action ="{{ url_for('form') }}" method="post">
Galactic Longitude: <input type="text" name="glon">
<button type="submit">Submit</button>
</form>
</body>
</html>
display.html
<!doctype html>
<body>
<p> {{ glon }} </p>
</body>
</html>

werkzeug.routing.BuildError with Flask Python

**difference to the suggested repeat, my error stemmed from the following line being missing in the original code session['message']=request.form['message'] wherease in the suggested duplicate was missing the render_template component`
I am trying to create user sessions with Flask, I don't care about authentication. I just want a page where they enter their name, and then they are redirected to the main page. I tried to follow the example in this link here but I get a werkzeug.routing.BuildError. To summarise my python app is:
from flask import Flask, render_template
from flask import request, session, url_for,abort,redirect
app = Flask(__name__)
app.config['SECRET_KEY'] = 'F34TF$($e34D';
#app.route('/')
def home():
return render_template('index.html')
#app.route('/signup', methods=['POST'])
def signup():
session['username'] = request.form['username']
session['message']=request.form['message']
return redirect(url_for('message'))
#app.route("/message")
def message():
return render_template("message.html")
if __name__ == '__main__':
app.run(debug=True)
and index.html is:
{% extends "layout.html" %}
{% block content %}
<h1>Say something</h1>
<form method="post" action="{{ url_for('signup') }}">
<p><label>Username:</label> <input type="text" name="username" required></p>
<p><button type="submit">Send</button></p>
</form>
{% endblock %}
layout.html is:
<!doctype html>
<html lang="en">
<head>
<title>Say somthing</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
You are getting that error because you don't have a route called message and yet you are redirecting to it.
#app.route('/signup', methods=['POST'])
def signup():
session['username'] = request.form['username']
# Create a message route first
return redirect(url_for('message'))
Here's a sample route called message
#app.route("/message")
def message():
return render_template("message.html")

Categories

Resources