Unable to add list to session in flask - python

I have simple input field where user is adding note.. and what ever note user is adding it will be displayed above in the list.. and m trying to store in a session in flask
This is my flask code
from flask import Flask, render_template, request, session
from flask_session import Session
app = Flask(__name__)
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
#app.route("/", methods=["GET", "POST"])
def index():
if session.get("notes") is None:
session["notes"]=[]
if request.method == "POST":
note = request.form.get("note")
session["notes"].append(note)
return render_template("session-index.html", notes=session["notes"])
if __name__ == "__main__":
app.run(debug=True)
And this is my html page
{% extends "inherit-layout.html" %}
{% block heading %}
Form Page
{% endblock %}
{% block body %}
<ul>
{% for note in notes %}
<li>{{ note }}</li>
{% endfor %}
</ul>
<form action="{{ url_for('index') }}" method="POST">
<input type="text" name="note" placeholder="Enter Note Here">
<button type="submit">Add Note</button>
</form>
{% endblock %}
What currently happening is when m adding note for second time it is replacing previous one in the list.

from flask import *
app = Flask(__name__)
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
app.config['SECRET_KEY'] = "asddaffffa"
#app.route("/", methods=["GET", "POST"])
def index():
if session.get("notes") is None:
session["notes"]=[]
if request.method == "POST":
note = request.form.get("note")
list = session["notes"]
list.append(note)
session["notes"] = list
return render_template("session-index.html", notes=session["notes"])
if __name__ == "__main__":
app.run(debug=True)
This should work..

Related

Passing argument to a flask GET function

I'm trying to write a simple messaging function and, despite searching, having trouble coming up with a workable solution. On the get function, the code retrieves stored messages and passes this to be rendered.
The post function stores the message which all works fine, however I'm trying to redirect the user back to the original page they came from to display the new message, hence trying to pass the receiving user variable to the get function.
My code so far below. I'm new to flask so would appreciate any other pointers as well. Thanks in advance!
#app.route("/messaging", methods=["GET", "POST"])
#login_required
def messaging():
if request.method == "GET":
clicked_user = request.args.get('user')
messages = db.execute("SELECT * FROM messages WHERE (m_sending_user = :self_user AND m_receiving_user = :other_user) OR (m_sending_user = :other_user AND m_receiving_user = :self_user)",
self_user = session["user_id"],
other_user = clicked_user)
return render_template("messaging.html", messages=messages, clicked_user=clicked_user)
if request.method == "POST":
receiving_user = request.form.get("recipient")
db.execute("INSERT INTO messages (m_sending_user, m_receiving_user, message) VALUES (:m_sending_user, :m_receiving_user, :message)",
m_sending_user = session["user_id"],
m_receiving_user = receiving_user,
message = request.form.get("reply"))
flash("Sent!")
return render_template("messaging.html")
Why do you not simply have the post function also call the get function like so
def get_function(clicked_user):
messages = db.execute("SELECT * FROM messages WHERE (m_sending_user = :self_user AND m_receiving_user = :other_user) OR (m_sending_user = :other_user AND m_receiving_user = :self_user)",
self_user = session["user_id"],
other_user = clicked_user)
return render_template("messaging.html", messages=messages, clicked_user=clicked_user)
#app.route("/messaging", methods=["GET", "POST"])
#login_required
def messaging():
if request.method == "GET":
clicked_user = request.args.get('user')
return get_function(clicked_user)
if request.method == "POST":
receiving_user = request.form.get("recipient")
db.execute("INSERT INTO messages (m_sending_user, m_receiving_user, message) VALUES (:m_sending_user, :m_receiving_user, :message)",
m_sending_user = session["user_id"],
m_receiving_user = receiving_user,
message = request.form.get("reply"))
flash("Sent!")
return get_function(m_receiving_user)
But of course with better named functions ;)
If you send data in GET request, it will be visible in URL parameter. Rather, you can use session object to store variable. More on session object can be found in the [official documentation on session object].(https://flask.palletsprojects.com/en/1.1.x/quickstart/#sessions)
You can use url_for with redirect method to redirect user to the original template.
Here I have shown a basic example:
messaging.html:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Post request redirect</title>
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% if clicked_user %}
Clicked user: {{ clicked_user }}
{% endif %}
{% if messages %}
Messages: {{ messages }}
{% endif %}
<h3>Send a Message</h3>
<form action='{{url_for("messaging")}}' method="post">
Recipient:
<input type="text" name="recipient">
<input type="submit" value="Submit">
</form>
</body>
</html>
app.py:
from flask import Flask, render_template, redirect, url_for, session, request, flash
app = Flask(__name__)
# Set the secret key to some random bytes. Keep this really secret!
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
#app.route("/messaging", methods=["GET", "POST"])
def messaging():
if request.method == "GET":
data = {
"shovon": "some messages for shovon",
"arsho": "other messages for arsho"
}
receiving_user = None
messages = None
if 'receiving_user' in session:
receiving_user = session["receiving_user"]
messages = data.get(receiving_user)
return render_template("messaging.html", messages=messages, clicked_user=receiving_user)
if request.method == "POST":
receiving_user = request.form.get("recipient")
session["receiving_user"] = receiving_user
flash("Sent!")
return redirect(url_for("messaging"))
Output:
Before form submission:
After form submission:
N.B.: Here I have mocked the database queries with static dictionary search.

I am unable to get data from flask forms [duplicate]

This question already has an answer here:
Form is never valid with WTForms
(1 answer)
Closed 3 years ago.
I have like a search bar built with wtforms, but I don't know for some reason I am unable to fetch data or value entered in the search bar. I tried almost everything from online tutorials but just couldn't find the solution. Below is my code examples.
For my search bar, I have tried form.search.data and request.form['search'] too but it's not working.
#flask_app.py
from flask import Flask, render_template, url_for, flash, redirect, request
from forms import SearchForm
app = Flask(__name__)
app.config['SECRET_KEY'] = '791628bb0b13ce0c676dfde'
#app.route('/')
#app.route('/home')
def home():
return render_template('home.html')
#app.route('/search', methods= ['GET', 'POST'])
def search():
form = SearchForm()
if form.validate_on_submit():
if form.search.data == 'admin':
return redirect(url_for('home'))
return render_template('search.html', form= form)
if __name__ == "__main__":
app.run(debug=True)
#forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired
class SearchForm(FlaskForm):
search = StringField('search', validators=[DataRequired()])
submit = SubmitField('Search')
#search.html
{% extends 'layout.html' %}
{% block content %}
<form action="" class="form-inline mt-4" method="POST">
<div class="form-group">
{{form.search(class= 'form-control', placeholder= 'Enter term to search')}}
{{form.submit(class= 'btn btn-outline-primary')}}
</div>
</form>
{%endblock%}
#home.html
{% extends 'layout.html' %}
{% block content %}
<h1>Welcome to homepage!</h1>
{%endblock%}
Is there any bug? I expect form.search.data should be able to fetch data from search bar.
You're not inserting the CSRF field in the HTML form which can be done via form.hidden_tag()
#search.html
{% extends 'layout.html' %}
{% block content %}
<form action="" class="form-inline mt-4" method="POST">
{{ form.hidden_tag() }}
<div class="form-group">
{{form.search(class='form-control', placeholder= 'Enter term to search')}}
{{form.submit(class='btn btn-outline-primary')}}
</div>
</form>
{% endblock %}
See this

Python - how to change flask template when session variable change?

Hi friend I want my template html file to display the loading spinner when session['train'] change. Here are the things I've tried but didn't work:
The html file:
<div class="messages">
{% block content%}
{% if session['training'] %}
<div class="spinner"><div class="double-bounce1"></div>
<div class="double-bounce2"><p style="font-weight:bold;font-size:16px;margin-left:-17px;color:white;">Training</p></div>
</div>
</div>
{% else %}
<div class="messages-content"></div>
</div>
<div class="message-box">
<textarea type="text" class="message-input" placeholder="Type message..."></textarea>
<button type="submit" class="message-submit">Send</button>
</div>
</div>
</div>
{% endif %}
{% endblock content%}
Python Code:
def retrain():
session['training']=True
app = Flask(__name__)
#app.route("/")
def home():
if session.get('logged_in'):
return render_template('index.html')
else:
return render_template('login.html')
#app.route('/login', methods=['POST'])
def login():
error = False
POST_USERNAME = str(request.form['username'])
POST_PASSWORD = str(request.form['password'])
Session = sessionmaker(bind=enginedb)
s = Session()
query = s.query(User).filter(User.username.in_([POST_USERNAME]), User.password.in_([POST_PASSWORD]) )
result = query.first()
if result:
session['logged_in'] = True ##for remember me function
flash('Login success')
return render_template('index.html')
else:
flash('Login failed!')
return render_template('login.html',error=True)
#app.route("/logout")
def logout():
session['logged_in'] = False
return home()
#app.route('/message', methods=['POST'])
def reply():
answer=response(request.form['msg'])
if "train" in answer:
retrain()
return jsonify( { 'text': answer})
The problem I'm encountering is that the spinner loader only display when I refresh my template page. I want whenever the variable "answer" in reply() contains "train", the template must auto reload and the spinner must be displayed!
The problem is that you are changing the session on the server in method reply(), but then returning json, and not returning anything that will cause the template to refresh or the session on the client to be updated.

Put form input in variable (Python, Flask)

I am trying to retrieve the form input and put it in my variable (test), this is what I tried:
from flask import Flask, redirect, render_template, request, url_for
import random
app = Flask(__name__)
app.config["DEBUG"] = True
vraag = "Wat is een barkie?"
ans = ['€10', '€50', '€100', '€1000']
#app.route("/")
def Q1():
random.shuffle(ans)
return render_template('main_page.html', vraag=vraag, ans=ans)
#app.route("/1", methods=["GET", "POST"])
def A1():
test = request.POST
return render_template('check.html', test=test)
main_page.html:
<body>
<p>{{ vraag }}</p>
{% for item in ans%}
<form method="POST" action="{{ url_for('A1') }}">
<input type="submit" name={{ item }} value={{ item }} />
</form>
{% endfor %}
</body>
What am I doing wrong here? As error code it gives 'Unhandled Exception'
request.POST in A1 is not correct. Additionally you should wrap item in quotes.
A1 should look like:
#app.route("/1", methods=["GET", "POST"])
def A1():
if request.method == 'POST':
return render_template('check.html', test=str(request.form))
else:
return "This page doesn't accept GET requests."
request.form is an ImmutableMultiDict object, so you can get exact arguments passed from the form. The above example is only to show you what got passed to the form.

Validate that a WTForms BooleanField is checked

I am creating a form using Flask-WTForms.
I am using a BooleanField so that a user can indicate they agree terms.
I cannot validate the BooleanField upon submission to ensure that it has been checked. I have tried using Required(), DataRequired() and custom validation but in each case I have not received a validation error.
Here are the nuts and bolts of the application:
from flask import Flask, render_template, session, redirect, url_for, flash
from flask_wtf import Form
from wtforms import BooleanField, SubmitField
from wtforms.validators import Required, DataRequired
from flask_bootstrap import Bootstrap
app = Flask(__name__)
app.config['SECRET_KEY'] = 'impossibletoknow'
bootstrap = Bootstrap(app)
class AgreeForm(Form):
agreement = BooleanField('I agree.', validators=[DataRequired()])
submit = SubmitField('Submit')
#app.route('/', methods=['GET', 'POST'])
def index():
form = AgreeForm()
if form.validate_on_submit():
agreement = form.agreement.data
if agreement is True:
flash('You agreed!')
return redirect(url_for('index', form=form))
form.agreement.data = None
agreement = False
return render_template('index.html', form=form)
if __name__ == '__main__':
app.run(debug=True)
And here is the index.html template...
{% import "bootstrap/wtf.html" as wtf %}
{% block content %}
<div class="container">
{% for message in get_flashed_messages() %}
<div class="alert alert-warning">
<button type="button" class="close" data-dismiss="alert">×</button>
{{ message }}
</div>
{% endfor %}
{{ wtf.quick_form(form) }}
</div>
{% endblock %}
Any suggestions would be gratefully received.
Works for me— you do need to use DataRequired() (Required is being deprecated):
from flask import Flask, render_template
from flask_wtf import Form
from wtforms import BooleanField
from wtforms.validators import DataRequired
app = Flask(__name__)
app.secret_key = 'STACKOVERFLOW'
class ExampleForm(Form):
checkbox = BooleanField('Agree?', validators=[DataRequired(), ])
#app.route('/', methods=['post', 'get'])
def home():
form = ExampleForm()
if form.validate_on_submit():
return str(form.checkbox.data)
else:
return render_template('example.html', form=form)
if __name__ == '__main__':
app.run(debug=True, port=5060)
Template:
<form method="post">
{{ form.hidden_tag() }}
{{ form.checkbox() }}
<button type="submit">Go!</button>
</form>
<h1>Form Errors</h1>
{{ form.errors }}
You do not have to include DataRequired() in your form, because it does not make sense, being a boolean. You must take of the incoming form data in the post method by saying if true.

Categories

Resources