AttributeError: 'function' object has no attribute 'method' - python

I have a web srv, and this is how i do my login
#app.route('/do_login', methods=['GET','POST'])
def do_login():
if request.method == 'POST':
email = request.form['email']
password = request.form['password']
So, when i run the app and i try to login i receive the error "AttributeError: 'function' object has no attribute 'method'"
This is also my html page
<div class="row">
<form action="{{ url_for('do_login') }}" method="POST" enctype="multipart/form-data">
<p>
<input type="text" name="email" placeholder="exmple#ex.it">
<input type="password" name="password" placeholder="*****">
<input type="submit" value="Login">
<a class = "nav-link" href="/registrazione">Registrati</a>
</p>
</form>
</div>

Make sure you have the line from flask import request in the file
Make sure you did not redefine request anyway. Either you have explicitly defined another function called request
def request():
...
or you have assigned a function to request
request = some_random_method

Related

When does Flask store the user's authentication?

I created this form:
<html>
<body>
<div>
<form action="{{ url_for('login') }}" method="POST">
<div class="row">
<div>
<input id="email" name="email" type="email" class="validate">
<label for="email">Email</label>
</div>
</div>
<div class="row">
<div>
<input id="password" type="password" name="password" class="validate">
<label for="password">Password</label>
</div>
</div>
<button type="submit" id="login" >Login</button>
<br>
</form>
<div>
</body>
</html>
and I have this Flask app that uses HTTPBasicAuth to do authentication.
#!flask/bin/python
from flask import Flask, jsonify, abort, request, make_response, url_for
from flask import render_template
from flask_httpauth import HTTPBasicAuth
#Needs: pip install flask-httpauth
app = Flask(__name__)
auth = HTTPBasicAuth()
#app.route('/', methods=['GET','POST'])
#auth.login_required
def login():
print('in login')
print(request.values.get('email'), request.values.get('password'))
templateToReturn = 'login.html'
if request.method == 'POST':
print('in post')
username = request.values.get('email')
password = request.values.get('password')
if verify_password(username, password):
print('password verified')
templateToReturn = 'index.html'
print('Curr user', auth.current_user())
print('request: ', request.method)
if request.method == 'GET' and auth.current_user():
templateToReturn = 'index.html'
return render_template(templateToReturn)
#app.route('/logout')
def logout():
return render_template('logout.html')
#auth.verify_password
def verify_password(email, password):
print('in verify pwd')
return verifyAuthentication(email, password)
def verifyAuthentication(email, password):
knownUsers = {'p1#gmail.com': 'pass',
'p2#yahoo.com': 'pass'}
authenticated = False
if email in knownUsers:
if knownUsers[email] == password:
authenticated = True
return authenticated
When I click the submit button of the form, I'm taken to the login() function. But isn't there supposed to be some way that it should go to the verify_password() function because it's decorated with #auth.verify_password?
How exactly and in which part of the code does the user authentication get registered with Flask? By which I mean: When does the #auth.login_required decorator actually allow their corresponding decorated functions to get executed?
Even the official page of HTTPBasicAuth() didn't explain this with an HTML example. Could someone please explain by adding to my code.
You forgot to add name attribute in your HTML input tag, so ideally it should be -
<input id="email" name="email" type="email" class="validate" />
<input id="password" name="password" type="password" class="validate" />

Footer contains a form with submit button that leads to "method not allowed"

I have a footer that contains a form on every page. I don't want the user to be redirected to a page when submitting the form. Instead, onclick button leads the user to a change in text in the footer on the same page. However, whenever the user inputs his email, and presses "enter" on the keyboard instead of the button, the page is immediately redirected to a "Method Not Allowed
The method is not allowed for the requested URL."
<form action="" method="POST">
<div id="theDiv" class="col-xl-auto col-md-6 col-12 pt-4 my-sm-0 order-6 ">
<div class="form-group"><label for="email" class="mb-3"><b>Subscribe to our Mailing list</b></label><input type="email" name="email" class="form-control form-control-lg" placeholder="Enter email" id="email"></div><button type="button" class="buttonsqred btn btn-primary btn-lg btn-block my-2 Subscribe mt-4 mb-3" onclick="document.getElementById('theDiv').textContent = 'You Successfully Subscribed!'; document.getElementById('theDiv').style.color = 'red'" >Subscribe</button>
</div>
</form>
#app.route('/subscribers', methods=['POST', 'GET'])
def subscribers():
title = "Subscribers"
if request.method == "POST":
subscriber_email = request.form['email']
new_subscriber = Subscribers(email=subscriber_email)
# Push to DB
try:
db.session.add(new_subscriber)
db.session.commit()
return redirect('/subscribers')
except:
return "There was an error adding your Subscription"
else:
return render_template("subscribers.html")
The action attribute on your HTML <form> tag is empty, that is why it does not work.
The action attribute should be /subscribers or {{ url_for('subscribers') }} if you want to use Jinja.
The type attribute of your <button> is button instead of submit, so clicking the button does not send the form.
Examples:
<form action="/subscribers" method="POST"> ... </form>
<!-- Jinja Example -->
<form action="{{ url_for('subscribers') }}" method="POST"> ... </form>
If you want to send the form without redirection, this question is already answered here (pure JavaScript solution): https://stackoverflow.com/a/54964425/11297557

Forbidden (403) CSRF verification failed. Request aborted when I hit the submit button

I'm working on the django authentification request and I get the forbidden error I checked my code but it doesn't seem I'm having an error.
HTML
<div class="grad"></div>
<div class="header">
<div>MLAT<span>SI</span></div>
</div>
<form action="{{views.login_user}}" method="POST">{% csrf_token %}
<div class="login">
<img src="{% static "img/Airplane.png" %}">
<div id="h" class="home">
<input type="text" placeholder="Login" name="username" value="">
<input type="password" placeholder="Mot de passe" name="password" value="">
<input style="float: left; width: 173px" type="submit" value="Log in" >
<input formaction="/form_registration.html/" style="float: right; width: 173px" type="submit" value="Register">
views.py
def login_user(request):
username = request.POST.get("username")
password = request.POST.get("password")
user = authenticate(username=username, password=password)
if user is not None and user.is_active:
login(request, user)
return HttpResponse("You're logged in.")
else:
return HttpResponse("Your username and password didn't match.")
you seem like you have a problem in the import package. And the way you're calling the views are incorrect you should read the Django documentation well
Looks like a duplicate of: Django - {% csrf_token %} was used in a template, but the context did not provide the value
Basically, your login_user view isn't making use of any render/context, hence the error (I don't know if that's the same view that is called when the url for login is called). So Django sees the csrf_token but never converts it to an actual token value.
from django.shortcuts import render
But really both your form and view look very wrong. The form action {{ views.login_user }} is incorrect. You can't call a view that way. And your Register button goes to what looks like an HTML page.

Django throwing "CSRF token missing or incorrect" Error (because of empty value of csrfmiddlewaretoken)

I recently got stuck with a pretty strange issue. I have a form in my template as follows:
<form class="form" id="loginForm" role="form" action="/user/login/"
method="POST">
{% csrf_token %}
<div class="form-group">
<input type="email" class="form-control" id="email" name="email"
placeholder="Enter email" value="">
</div>
<div class="form-group">
<input type="password" class="form-control" id="password"
name="password" placeholder="Password" value="">
</div>
<div class="cl-effect-7">
<button type="submit" class="btn btn-primary">SIGN IN</button>
</div>
</form>
I was getting CSRF token missing or incorrect. Digging further deep down i found that though csrftoken cookie is getting correctly set in the browser the POST request is having empty value of csrfmiddlewaretoken and hence it throws the error with the said reason.
Also here is my view(though I doubt if there is anything wrong with it)
def user_login(request):
context = RequestContext(request)
if request.method == 'POST':
email = request.POST['email']
password = request.POST['password']
user = authenticate(username=email, password=password)
if user:
if user.is_active:
login(request, user)
return HttpResponseRedirect('/user/')
else:
return HttpResponse("Your account is disabled.")
else:
return HttpResponse("Invalid login details supplied.")
else:
return render_to_response('user/login.html', {},context_instance = context)
Here's the other view which redirects to login.html:
def index(request):
context_dict = {}
template = "user/login.html" #default template to render
user = None
user_profile = None
user = request.user.id
if user != None:
user_profile,created = UserProfile.objects.get_or_create(user=user)
#Check whether the user is new,if yes then he needs to select btw Mentor-Mentee
if user_profile and user_profile.is_new:
context_dict['selected'] = None
template = "user/select.html" #User has to select either Mentor/Mentee,so redirect to select.html
return render_to_response(template,context_dict,context_instance = RequestContext(request))
Now I used little JavaScript to get around this, by setting the value of csrfmiddlewaretoken from the cookie manually but that's a little strange behavior from Django.
PS: Im using Django 1.7 and tested this on all browsers.
Try adding this to your form:
<div style="display:none">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
</div>
Source: https://docs.djangoproject.com/en/dev/ref/csrf/#other-template-engines

Flask : ImmutableMultiDict has no attribute

I wrote a small flask file:
myapp.py
#APP.route('/login', methods=['GET','POST'])
def login():
return flask.render_template('login.html')
#APP.route('/loginNext', methods=['POST','GET'])
def loginNext():
user=request.form.username
passw=request.form.password
return str(user)+str(pass)
login.html
<form id="foo" method="post" action="/loginNext">
Username : <input type="text" name='username' value="admin">
Password : <input type="password" name='password' value="">
<input type="submit" name="submit" value="Submit">
</form>
When I am trying to do request.form.username, I am getting
*AttributeError: 'ImmutableMultiDict' object has no attribute 'username' *
I read on stackoverflow as well as other places but didnot work. I tried doing request.form.get('username',None') that did not fetch the username.
<input type="text" name='username' value="admin"> was your input in .html file so to access in flask It is done in this way
username = request.form['username']
and you get the data as username .. same for password also.
if form tag contains below:-
<input type="text" name='username'>
In Flask Function, we can access it in 2 ways:-
username = request.form['username']
username = request.form.get('username')

Categories

Resources