I am trying to do a log in in django/python.
I have this in my views.py:
#csrf_exempt
def Principal(request):
context = {}
if request.method != 'GET':
context = {
'title': '405 Method Not Allowed',
}
if request.user.is_authenticated():
logged_q = 'Logged in as '+ request.user.username
logged = True
else:
logged_q = 'Not logged in.'
logged = False
print (logged_q)
top_aparcamientos = Aparcamiento.objects.all()
#top_aparcamientos = Comentario.objects.all().order_by('-aparcamiento__id').unique()[:5]
pagina_list = Pagina.objects.all()
context['top_aparcamientos'] = top_aparcamientos
context['pagina_list'] = pagina_list
usuario = request.user.username
context = {
'usuario' : usuario,
'logged' : logged
}
return render_to_response('index.html', context
So, for do my template, I take the variable logged in my base.html like that:
{% if logged %}
<div class ="container_corner">
<div class="topright">
<span id="corner_message"><strong>Bienvenido,</strong> <span class="oblicuo">{{usuario}}</span></span>
Salir</button><br>
</div>
</div> {% else %}
<form id="login_form" action="login/" method ="POST">
{% csrf_token %}
<label for="id_username"><span class="login_fields">Nick: </span></label> <input id="id_username" maxlength="254" name="username" type="text" />
<label for="id_password"><span class="login_fields">ContraseƱa: </span></label> <input id="id_password" name="password" type="password" />
<button type="submit">Login</button>
</form> {% endif %}
But it gives me this error when I try to log in:
Forbidden (403) CSRF verification failed. Request aborted. Help Reason given for failure: CSRF token missing or incorrect.
Do I need anymore {% csrf_token %}? Where?
Thank you!
Instead of {% csrf_token %}, you can probably use
<input type='hidden' name='csrfmiddlewaretoken' value='{{ csrf_token }}' />
Or you can also use {{ csrf_input }}.
<form action="login/" method="post">{{ csrf_input }}
Related
I'm want to log a user in, in simple web site.
i tried to create my own login authentication but it send this error:
AttributeError at /login/ , 'QuerySet' object has no attribute 'pk'
this is the code (views.py) :
...
from django.contrib.auth import login as login_module
def login(request):
if request.method == "POST":
Login = LoginFrom(request.POST)
if Login.is_valid():
user = Login.cleaned_data
if User.objects.filter(username=user['username']).exists():
user_info = User.objects.filter(username=user['username'] ,
password=user['password']).values('name')
if user_info.exists():
login_module(request, user_info)
messages.success(request, 'welcome {}'.format(user_info[0]['name'] ) , 'welcome_message')
else:
messages.error(request, 'wrong password', 'password_message')
else:
messages.error(request, 'username doesn\'t exist', 'username_message')
else:
Login = LoginFrom()
return render(request, 'login.html')
then i replace it with this code that's from django document; it get me into another problem which is always return 'None':
views.py
...
...
from django.contrib.auth import authenticate
from django.contrib.auth import login as login_module
def login(request):
if request.method == "POST":
Login = LoginFrom(request.POST)
if Login.is_valid():
cd = Login.cleaned_data
user = authenticate(request, username = cd['username'], password = cd['password'])
if user is not None:
login_module(request, user)
messages.success(request, 'login', 'welcome_message')
else:
messages.error(request, 'error (none)', 'error_message')
else:
Login = LoginFrom()
return render(request, 'login.html')
(form.py) in both way:
class LoginFrom(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
login.html:
<!DOCTYPE html>
<html>
<head><title>login</title></head>
{% include 'header.html' %}
<body class="background">
<form id="login_form" action="" method="POST">
{% csrf_token %}
<p class="lead">login to your account</p>
<div class="form-group">
<br>
<div class="input-group">
<div class="input-group-text" id="basic-addon1"><i class="bi bi-people"></i></div>
<input type="text" name="username" class="form-control" placeholder="Enter Your Username"required>
</div>
<div>
{% if messages %}
{% for message in messages %}
{% if 'username_message' in message.tags %}
<div class="text-danger" > {{message}} </div>
{% endif %}
{% endfor %}
{% endif %}
</div>
</div>
<div class="form-group">
<br>
<div class="input-group">
<div class="input-group-text" id="basic-addon1"><i class="bi bi-key"></i></div>
<input type="password" name="password" class="form-control" placeholder="Enter Your password" required>
</div>
<div>
{% if messages %}
{% for message in messages %}
{% if 'password_message' in message.tags %}
<div class="text-danger" > {{message}} </div>
{% endif %}
{% endfor %}
{% endif %}
</div>
</div>
<br>
<button class="btn btn-outline-secondary" type="submit" name="login" value="login" >Login</button>
<div>
{% if messages %}
{% for message in messages %}
{% if 'welcome_message' in message.tags %}
<div class="text-warning text-center" > {{message}} </div>
{% endif %}
{% endfor %}
{% endif %}
</div>
</form>
</body>
</html>
models.py
class User(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField()
username = models.CharField(max_length=100)
password = models.CharField(max_length=100)
comment_count = models.IntegerField(default=0)
did i missed some part or should set some setting?
In your first solution,
password=user['password']
will always fail as the password saved in default auth_user table will have the password hashed.
I tried the second solution and it is working fine. That login view cannot return None because the only return statement is returning render method.
Can you please share the login.html template.
Here is my template, the if statements aren't working!
{% extends "auctions/layout.html" %}
{% block body %}
{% if bid.name == User %}
<br>
<h1>You Won the auction</h1>
<br>
{% endif %}
<h1>Title: {{title}}</h1>
<br>
<h1>Seller: {{listing.name}}</h1>
<br>
<h1>Description: {{listing.description}}</h1>
<br>
<h1>Category: {{listing.category}}</h1>
<br>
<h1>price: {{bid.price}} by {{bid.name}}</h1>
<br>
<form action="{% url 'Bid' %}" method="post">
{% csrf_token %}
<input type="hidden" name="title" value="{{title}}">
<input type="number" name="price">
<input type="submit">
</form>
<form action="{% url 'watchlist'%}" method="post">
{ % csrf_token %}
Add to watchlist
<input type="hidden" name="form_type" value="Watchlist">
<input type="hidden" name="title" value="{{title}}">
<input type="submit">
</form>
{% if User == "ilias" %}
<br>
<h1>Close the auction</h1>
<br>
<form action="{% url 'close' %}" method="post">
{% csrf_token %}
<input type="hidden" name="title" value="{{title}}">
<input type="submit">
</form>
<br>
{% endif %}
<form action="{% url 'comment'%}" method="post">
{% csrf_token %}
<h1>Add comment</h1>
<input type="text" name="content">
<input type="hidden" name="title" value="{{title}}">
<input type="submit">
</form>
{%for item in comments%}
<h3>{{item.content}} by {{item.name}}</h3>
<br>
{%endfor%}
{% endblock %}
Here is my views.py
def listings(request, title):
try:
listing = Listing.objects.get(title=title)
except:
return HttpResponse('<h3>Page not found</h3>')
else:
title = listing.title
name = listing.name
comments = comment.objects.filter(title=title)
bid = Bid.objects.get(title=title)
User = request.user.username
print name
return render(request, 'auctions/listing.html', {
'listing': listing,
'title': title,
'comments': comments,
'bid': bid,
'User': User,
'name': name,
})
I can't figure out where is the error. How can I fix this error and how to avoid this types of errors? Django version: Django 3.1.1, Python version: Python 3.8.5
If you need more information ask me in the comments!
It doesn't show the content of the if statements! I don't know why. The views is properly sending data it checked it!
Fixed the error just needed to make them both strings
def listings(request, title):
try:
listing = Listing.objects.get(title=title)
except:
return HttpResponse('<h3>Page not found</h3>')
else:
title = listing.title
name = str(listing.name)
comments = comment.objects.filter(title=title)
bid = Bid.objects.get(title=title)
User = str(request.user.username)
bidder = str(bid.name)
print(name)
return render(request, "auctions/listing.html", {
"listing":listing,
"title":title,
"comments":comments,
"bid":bid,
"User":User,
"name":name,
"bidder":bidder
})
I have two forms on a page. The first form properly sends a POST request to my view but the second form sends a GET (I need it to also send a POST). I've made this mistake before and this time I made sure that the button is set to "submit", but for some reason it still sends a GET.
form 1 (working as intended):
<form method="POST">
{% csrf_token %}
<div class="row form-row">
<div class="col-sm-6">
<div class="form-group">
<label for="start_date">Start</label>
<input class="form-control" type="text" data-flatpickr data-alt-input="true" data-date-format="Y-m-d" name="start_date" data-enable-time="true">
</div>
<div class="form-group">
<label for="end_date">End</label>
<input class="form-control" type="text" data-flatpickr data-alt-input="true" data-date-format="Y-m-d" name="end_date" data-enable-time="true">
</div>
</div>
</div>
<input type="hidden" name="eventtype" value="availability">
<button class="btn btn-primary" type="submit">Save changes</button>
</form>
form 2 (sends a GET but I want this to POST):
<form method="POST">
{% csrf_token %}
{% if form.errors %}{{form.errors}}{% endif %}
<input type="hidden" name="pk" value="{{ i.id }}">
<input type="hidden" name="eventtype" value="invite">
<button class="btn btn-primary" type="submit">Confirm</button>
</form>
views.py
def createevent(request):
if request.method == 'GET':
<<code>>
else:
try:
eventtype = request.POST.get('eventtype', None)
print(eventtype)
if eventtype == "availability":
form = EventForm(request.POST)
newEvent = form.save(commit=False)
newEvent.mentor_user = request.user
newEvent.requester_user = None
newEvent.notes = None
newEvent.save()
elif eventtype == "invite":
form = EventForm(request.POST)
updatedEvent = form.save(commit=False)
updatedEvent.isConfirmed = True
updatedEvent.save()
return redirect('createevent')
except ValueError:
print(form.errors)
return render(request, 'events/createevent.html', {'form':EventForm(), 'error':'There was an error. Please make sure you entered everything correctly!'})
urls.py
# Events
path('events/create', views.createevent, name='createevent'),
# path('calendar/<slug:slug>', views.viewevent, name='viewevent'),
path('events/<int:pk>/edit', views.updateevent, name='updateevent'),
console output for form 1 and form 2:
"GET /events/create?csrfmiddlewaretoken=<<redacted>>&pk=2&eventtype=invite HTTP/1.1" 200 25560
"POST /events/create?csrfmiddlewaretoken=<<redacted>>&pk=2&eventtype=invite HTTP/1.1" 302 0
Set the action of form to your url path.
Look at this:
<form name="form" method="POST" action="{% url 'your_url_name' %}">
The issue ended up being the form was wrapped in another form tag further up in the template code. When I clicked the Submit button, the Submit button was firing on the first form and not the second. Just a bad copy/paste.
I'm trying to get a simple form set up in Flask for my own education. I've got a login.html page with this form code:
<form action="{{ url_for('login') }}" method="post">
<div>
<label for="username">Username</label>
<div>
<input type="text" id="username" name="username" placeholder="Username">
</div>
</div>
<div>
<label for="password">Password</label>
<div>
<input type="password" id="password" name="password" placeholder="Password">
</div>
</div>
<div >
<input class="btn" type="submit">
</div>
</form>
I'm using code like the following to receive it, but Flask returns an empty request.form so I can't process it.
#app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
request.form['username']
...
I really don't want to learn another library (WTForms) right now, and I'm using bootstrap so that will add to the headache. What am I not seeing here with Flask/HTML?
I had this problem, but it was because I forgot to assign a name attribute to my input elements and I was trying to refer access the form data by the id attribute instead
i.e.
My HTML and Python was as shown below
HTML
<input type="text" id="usernameTxtBx">
Python
request.form['usernameTxtBx']
What I have done now:
HTML
<input type="text" name="username" id="usernameTxtBx">
Python
request.form['username']
I also needed to ensure that I was using a POST request. A GET request gave me an empty dictionary in my python code.
The OP made neither of these mistakes. But this may help someone that stumbles on this thread.
I had that problem.
Some tools like postman or some libraries or web browser sends the data in a way that flask does not identify as posted values. From my point of view this is a flask issue.
This is the workaround I followed to solve it:
1 - I sent the information using json. Have a look to this:
How to send a JSON object using html form data
2 - I instead of getting the parameters using:
value = request.form["myparamname"]
I used this:
json_data = request.get_json(force=True)
value = json_data["myparamname"]
just use request.get_json() in POST requests
login.html
{% extends "layout.html" %}
{% block content %}
<div class="form">
<h2>Sign In</h2>
{% for field in form.errors %}
{% for error in form.errors[field] %}
<div class="alert alert-error">
<strong>Oops...</strong> {{error}}.
</div>
{% endfor %}
{% endfor %}
<form action="{{ url_for('login') }}" method=post>
{{ form.hidden_tag() }}
{{ form.email.label }}
{{ form.email }}
{{ form.password.label }}
{{ form.password }}
<p> <input id="submit" name="submit" type="submit" class="btn btn-inverse" value="Sign In"></p>
</form>
</div>
{% endblock %}
forms.py
class SigninForm(Form):
email = TextField("email", [validators.Required("Please enter your email")])
password = PasswordField('Password', [validators.Required("Please enter a password.")])
submit = SubmitField("Sign In")
Then import the signinform in your views and create your login method like this
#app.route('/login', methods=['GET', 'POST'])
def signin():
form = SigninForm()
if form.validate_on_submit():
session['email'] = form.email.data
flash('You are logged in')
return redirect(url_for('dashboard'))
return render_template('signin.html', form=form)
Refer this tutorial for more detailed instructions
http://pypix.com/python/building-flask-blog-part-1/
I'm trying to create a login and logout page with django. The problem I have is that when I submit the form, it doesn't go the url which I specified. When I click the login button, I want it to go to http://127.0.0.1:8000/home/ but instead, it goes to http://127.0.0.1:8000/?next=/home/.
Below is my login/logout code in my view.py:
def login(request):
def errorHandler(error):
return render_to_response('login.html', {'error' : error})
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(username = username, password = password)
if user is not None:
if user.is_active:
authLogin(request, user)
fullName = user.get_full_name
return render_to_response('logged_in.html', {'full_name': fullName})
else:
error = 'Account disabled.'
return errorHandler(error)
else:
error = 'Invalid details entered.'
return errorHandler(error)
return render_to_response('login.html')
#login_required
def logout(request):
authLogout(request)
return render_to_response('logged_in.html')
my login.html:
{% extends "base.html" %}
{% block content %}
{% if error %}
<p><b><font color="red">Error: </font></b>{{ error }}</p>
{% endif %}
<form action="/home/" method="post">
<label for="username">User name:</label>
<input type="text" name="username" value="" id="username">
<label for="password">Password:</label>
<input type="password" name="password" value="" id="password">
<input type="submit" value="Login" />
<input type="hidden" name="next" value="{{ next|escape }}" />
</form>
{% endblock %}
my logged_in.html:
{% extends "base.html" %}
{% block name %}{{ full_name }} is {% endblock %}
{% block content %}
<p><a href='/'>Logout</a></p>
{% endblock %}
url:
(r'^$', 'myapp.views.login'),
(r'^home/$', 'myapp.views.logout'),
Please help
The problem is that you don't actually login the user, the form sends unauthenticated user to /home/, which can't process, because it requires login. :-) So it redirects user to login view, storing the destination in next parameter.
Solution:
<form action="" method="post">
maybe you should try to remove hidden input with name="next"
http://docs.djangoproject.com/en/1.2/topics/auth/#django.contrib.auth.views.login