Flask & HTML, form not Submitting - python

Website Link: Click Me
The "Next" button isn't submitting. My HTML Code is:
{% extends "layout.html" %}
{% block main %}
<div style='float:left;width:70%;'>
<div style='margin-top:200px;'>
<form method='POST' action='/login1'>
<input type='hidden' value="{{path}}">
<input style='width:800px;height:60px;font-size: 2em;' type='email' placeholder='Type your email to continue...' name='email' value="{{name}}">
<style>
.sub:hover{
border-style:none;
}
.sub{
border-style:none;
}
</style>
<input class='sub' type='submit' value='Next' style='height:75px;'>
</form>
</div>
</div>
<div style='float:left;width:20%;'>
<!--<img height="100%" src='static/assets/AccountBanner.png'>!-->
</div>
{% endblock %}
My Python Flask code is:
#app.route('/login')
def login():
username = request.cookies.get('login')
psw = request.cookies.get('psw')
if 'login' in request.args.get('path'):
return redirect('/login?path=/')
if username == None:
return render_template('login/index.html',path = request.args['path'])
with open('static/json/members.json') as a:
a = json.load(a)
found = False
for i in a:
if i["email"] == username:
if str(i["password"]) != str(psw):
return redirect('/')
else:
found = True
if found == False:
return render_template('login/index.html',path=request.args['path'])
return redirect('/')
#app.route('/login1', methods=['POST'])
def main1():
return render_template('password.html',redirect1 = "/login1"+request.args['path'])
What I am trying to do is asking the user for his/her email and then render a page asking for a password. However, the submit button isn't working. I am using action and method=POST submit.

Ok, I know why it didn't work.
Everytime I make an error (syntax error) OR I POST to a 404 page, I have a 404 and 500 function where it makes you login before viewing the 404/500 page. That's why it kept on redirecting to the original login page. It works now.

Related

How do I show an error message when I have an invalid log in?

I'm working on a web app right now and I don't know how to display an error message when the user types in an invalid log in name. How do I go about this?
this is my login.html
{% block body %}
<h1>Login</h1>
{% if error %}
<p>Invalid Username</p>
{% endif %}
<form method="POST" action="{{ url_for('login') }}">
<input type="text" name="username" placeholder="Your Username">
<input type="submit" value="Submit">
</form>
<a href='{{variable6}}'>Sign Up</a>
{% endblock %}
this is my app.py
#app.route("/login", methods=["GET", "POST"])
def login():
if flask.request.method == "GET":
return flask.render_template("login.html")
if flask.request.method == "POST":
username = flask.request.form["username"]
cursor.execute(
"SELECT user_name FROM public.users WHERE user_name = %s", [username]
)
results = cursor.fetchall()
if len(results) != 0: # if a user exists, "log" them in
return flask.redirect(flask.url_for("main"))
else:
return flask.render_template("login.html")
I believe that your problem is that you are not defining what the "error" variable is, you could fix this by when you are returning the render_template in the last line of app.py, adding error=True, leaving you with this as your last line for app.py.
return flask.render_template("login.html", error=True)
As otherwise Jinja (the templating language you used in login.html) would not know what error and would get the type None as the value of error in the {% if error %} statement in login.html and since None is not equal to true, it would skip over the code you want to run.
Hope this helps :)

Change password form not working in flask

I am trying to build a simple web app, which has a form to change one's password. I am using werkzeug.security functions (check_password_hash and generate_password_hash) to do so. This two functions work perfectly in during registering and logging in. But for some reason, when I change password, the password just doesn't match. I even wrote a code to check the password right away, passwordChange = check_password_hash(newHash, newPassword), then print(f'\n\n{passwordChange}\n\n')but for some reason it always returned false. Here is the full code. Any response is greatly appreciated :)
FLASK
#app.route("/passwordchange", methods=["GET", "POST"])
#login_required
def changepassword():
""""Change users' password"""
if request.method == "POST":
newPassword = request.form.get("newPassword")
newConfirmation = request.form.get("newConfirmation")
# Ensure that the user has inputted
if (not newPassword) or (not newConfirmation):
return apology("Please fill all of the provided fields!", 400)
# Check to see if password confirmation were the same or not
if newPassword != newConfirmation:
return apology("password did not match with password (again)", 400)
user_id = session["user_id"]
newHash = generate_password_hash("newPassword")
db.execute("UPDATE users SET hash = ? WHERE id = ?", newHash, user_id)
passwordChange = check_password_hash(newHash, newPassword)
print(f'\n\n{passwordChange}\n\n')
return redirect("/login")
else:
return render_template("password.html")
HTML
{% extends "layout.html" %}
{% block title %}
Change Password
{% endblock %}
{% block main %}
<form action="/passwordchange" method="post">
<div class="form-group">
<input class="form-control" name="newPassword" placeholder="New Password" type="password">
</div>
<div class="form-group">
<input class="form-control" name="newConfirmation" placeholder="New Password (again)" type="password">
</div>
<button class="btn btn-primary" type="submit">Change Password</button>
</form>
{% endblock %}

Issue with csrf_token while using Flask and WTForms

I'm trying to set up a basic "Contact" form for my website, which will basically take in values and then put them into a CSV file. The issue I'm having is that the entries cannot be validated cause they're missing a csrf_token?
Here's the relevant code from my app.py:
#app.route('/contact_end', methods=['POST'])
def handle_contact():
form = ContactForm()
print(form.name.data)
if form.validate_on_submit():
print("yup")
with open('data/messages.csv', 'a') as f:
print("oh shit")
writer = csv.writer(f)
writer.writerow([form.name.data, form.email.data, form.message.data])
print("waddup")
return redirect(url_for('contact_handler.html'), name=form.name.data)
print(form.errors)
return render_template('contact.html', form=form)
It skips over the if statement as it never ends out printing the "yup", and instead it prints out the error:
{'csrf_token': ['The CSRF token is missing.']}
The template that this connects to is:
{% extends "base_template.html" %}
{% block title %}Contact us {% endblock %}
{% block content %}
<p>Feel free to use the contact form below to send us any questions you might have.</p></br>
<form action="/contact_end" method="post">
{{ form.csrf_token }}
<label>Your Name <input type="text" name="name"/></label></br>
<label>Your Email <input type="text" name="email"/></label></br>
<label>Your Name <textarea name="message"></textarea></label></br>
<button type="submit">Send</button>
<button type="reset">Clear</button>
</form>
{% endblock %}
I've tried messing with form.csrf_token and .hidden_tags(), but with no success.
As well, this is the initial part of app.py that brings you to the page in the first place, the one above is the endpoint for the form:
#app.route('/contact')
def contact():
return render_template('contact.html', form=form)
Finally, here's my ContactForm class:
class ContactForm(FlaskForm):
print("yep")
name = StringField('Name', validators=[InputRequired()])
email = EmailField('Email', validators=[InputRequired(), Email()])
message = TextAreaField('Message', validators=[InputRequired()])
I've made sure to set my secret key, as well. Anyone have any idea why this isn't working? Many thanks.
You still need to create the form instance in your contact() function:
#app.route('/contact')
def contact():
form = ContactForm()
return render_template('contact.html', form=form)

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.

Django form.is_valid() always false

I'm coding a login. When I programmed the form by hand I got it working.
The code below works:
views.py
def login_view(request):
if request.method == 'GET':
return render(request, 'app/login.htm')
if request.method == 'POST':
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username, password=password)
if user is None:
return HttpResponseRedirect(reverse('error'))
if not user.is_active:
return HttpResponseRedirect(reverse('error'))
# Correct password, and the user is marked "active"
auth.login(request, user)
# Redirect to a success page.
return HttpResponseRedirect(reverse('home'))
template:
<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<p><label for="id_username">Username:</label> <input id="id_username" type="text" name="username" maxlength="30" /></p>
<p><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /></p>
<input type="submit" value="Log in" />
<input type="hidden" name="next" value="" />
</form>
Great! But now I want to do the same thing using Django's forms.
The code below is not working because I get is_valid() == False, always.
views.py:
def login_view(request):
if request.method == 'POST':
form = AuthenticationForm(request.POST)
print form.is_valid(), form.errors, type(form.errors)
if form.is_valid():
## some code....
return HttpResponseRedirect(reverse('home'))
else:
return HttpResponseRedirect(reverse('error'))
else:
form = AuthenticationForm()
return render(request, 'app/login.htm', {'form':form})
template:
<form action="{% url 'login' %}" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
There are a bunch of people on stackoverflow complaining that they get is_valid always false. I have read all those posts, and as far as I can tell I'm not making any of those mistakes. I found a new mistake to make :-)
EDIT: I added a print in the code. The output when opening the login view and submitting is
[27/Dec/2013 14:01:35] "GET /app/login/ HTTP/1.1" 200 910
False <class 'django.forms.util.ErrorDict'>
[27/Dec/2013 14:01:38] "POST /app/login/ HTTP/1.1" 200 910
and so is_valid() is False, but form.errors is empty.
It turns out that Maxime was right after all (sorry) - you do need the data parameter:
form = AuthenticationForm(data=request.POST)
The reason for that, though, is that AuthenticationForm overwrites the signature of __init__ to expect the request as the first positional parameter. If you explicitly supply data as a kwarg, it will work.
(You should still leave out the else clause that redirects away on error, though: it's best practice to let the form re-render itself with errors in that case.)
Check out form.errors which will help you find out why.
If situation arises, that you don't have an option (I was trying to work with bootstrap modals and it was just not working), I had to do this, or else the modal would always trigger even if the form had not issues (and the is_valid is always False by default)
What I needed:
Show modal when I click a button
if errors, show on the same page, the modal, with the error.
In the modal template:
{% if not brand_form.is_valid and brand_form.errors %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(window).on('load', (function() {
$('#brandAddModal').modal('show');
}));
</script>
{{ brand_form.non_field_errors }}
{% endif %}
In the view:
def add_brand_form(request):
form = BrandForm()
if request.method == 'POST':
form = BrandForm(data=request.POST)
if form.is_valid():
return HttpResponseRedirect('/home')
else:
return render(request, template_name='home.html', context={'brand_form':form})
return render(request, template_name='modal_add_brand.html', context={'brand_form':form})

Categories

Resources