I am having an issue with successfully calling a redirect after a user tries to log in (successful or unsuccessfully). In the console, I did notice that the GET and POST statements are correct. Thank You all in advance as this is a becoming a royal PIA.
views.py
class UserLoginFormView(View):
form_class = UserLoginForm
template_name = 'home/login.html'
#Display Blank Form
def get(self,request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
#Process Form Data
def post(self,request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
return redirect('products')
urls.py
urlpatterns = [
url(r'^$', views.HomeView, name='home'),
url(r'^register/$', views.UserFormView.as_view(), name="register"),
url(r'^login/$', views.UserLoginFormView.as_view(), name="user_login"),
url(r'^products/$', views.ProductsView, name="products"),
]
login.html
<form class="cozy" action="" method="post">
{% csrf_token %}
<div class="form-group control">
<label for="username" class="control-label">Username</label>
<input type="text" name="username" id="username" class="form-control">
</div>
<div class="form-group control">
<label for="password" class="control-label">Password</label>
<input type="password" name="password" id="password" class="form-control">
</div>
{% if form.errors %}
<p class=" label label-danger">
Your username and password didn't match. Please try again.
</p>
{% endif %}
<div class="d-flex align-content-center justify-content-center">
<button type="submit" class="btn btn-lg btn-accent">Login</button>
</div>
</form>
Console Output
System check identified no issues (0 silenced).
January 25, 2019 - 15:39:24
Django version 1.11.18, using settings 'svcreporter.settings'
Starting development server at http://127.0.0.1:9000/
Quit the server with CTRL-BREAK.
[25/Jan/2019 15:39:28] "GET /home/login/ HTTP/1.1" 200 4490
[25/Jan/2019 15:39:34] "POST /home/login/ HTTP/1.1" 302 0
[25/Jan/2019 15:39:34] "GET /home/ HTTP/1.1" 200 17242
You missed the as_view() part in:
urlpatterns = [
url(r'^$', views.HomeView, name='home'),
# ...
]
it should be:
urlpatterns = [
url(r'^$', views.HomeView.as_view(), name='home'),
# ...
]
and I would say that in some point you'll be struggling with this too:
# Add .as_view() to views.ProductsView
url(r'^products/$', views.ProductsView, name="products")
Related
I'm using class based views to render a template. In that same class, I also have a post request to allow for the submission of a form.
However, when I submit the form, I get the CSRF cookie not set error. I did use the {% csrf_token %} but still doesn't work.
Here is my code:
class SignIn(View):
def get(self, request):
# email = request.POST['email']
# password = request.POST['password']
template = loader.get_template('signin.html')
logging.info(request)
return HttpResponse(template.render())
def post(self, request):
email = request.POST['email']
password1 = request.POST['password1']
password2 = request.POST['password2']
template = loader.get_template('signin.html')
logging.info(request.__dict__)
logging.info(password1)
logging.info(email)
if User.objects.filter(email=email).exists():
messages.info(request, 'E-mail Exists!')
return redirect('signup')
elif password1 != password2:
messages.info(request, 'PASSWORD DOESNT MATCH')
return redirect('signup')
new_user = User.objects.create_user(email, email, password1)
return HttpResponse(template.render())
This is my template:
<html>
<div>
<p>
Signup
</p>
<form method = "POST" action="/signup">
{% csrf_token %}
username:
<br/>
<input type="text" name="email" />
<br/>
Password:
<br/>
<input type="password" name="password1" />
<br/>
confirm Password:
<br/>
<input type="password" name="password2" />
<br/>
<input class ="btn btn-primary" type="submit" value= "signup" />
<br/>
</form>
</div>
</html>
My urls.py:
from django import views
from django.urls import path
from .views import SignUp, SignIn, Index
urlpatterns = [
path('', Index.as_view(), name='Index'),
path('signup', SignUp.as_view(), name='SignUp'),
path('signin/', SignIn.as_view(), name='SignIn')
]
I am trying to authenticate a registered user . redirect is not working in my case. after clicking the login button it keep on showing the login page again. i want the user to go to home page upon the successful login. Here are my files.
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponseRedirect
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout
def register_new_a(request):
saved = False
if request.method == "POST":
# take whatever is posted to the Details Form
form = DetailsForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Your account details have been saved!')
return HttpResponseRedirect('/register_new_a?saved=True')
else:
form = DetailsForm()
if 'saved' in request.GET: # sends saved var in GET request
saved = True
return render(request, 'register1.html', {'form': form, 'saved': saved})
def loginUser(request):
if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
# at backend authenticated the credentials
login(request, user)
return redirect('home') # not working
return render(request, 'login_a.html')
urls.py
from django.contrib import admin
from django.urls import path
from home import views
urlpatterns = [
path("", views.index, name='home'),
path("login", views.loginUser, name='login'),
path("logout", views.logoutUser, name='logout'),
#path("register", views.register, name='register'),
path("register_new_a", views.register_new_a, name='register_new_a'),
path("register_new_b", views.register_new_b, name='register_new_b'),
path("about", views.about, name='about'),
]
login_a.html
{% extends 'base.html'%}
{% block title %}Login{% endblock title %}
{% block body %}
<div class="container my-3" >
<h1 class="display-3" align="center">Login Here</h1>
<br>
<h1 class="display-6" >STEP 1: </h1>
<form method="post" action="">
{% csrf_token %}
<div class="mb-3">
<label for="Username1" class="form-label" >Username </label>
<input type="username"class="form-control" name="username"></input>
</div>
<div class="mb-3">
<label for="Password1" class="form-label">Password</label>
<input type="password" class="form-control" id="Password1" name="password">
</div>
New user? Register Here
<button type="submit" class="btn btn-primary float-end" style="background: #0a9396" > Next</button>
</form>
</div>
{% endblock body %}
Any help would be appreciated.
I want to know that if I am using the action in login.html <form > tag and if not using it, In both cases all is good. I am able to successfully login and if there is any error, my views.py showing the respective errors.
I think after rendering the template the django automatically send the data back to user_login function in views.py without specifying the action attribute to the <form > tag.
I just want to know that when do I need to use action attribute in the <form > tag in django template.
My urls.py
from django.urls import path
from . import views
# TEMPLATE URLS!
app_name = 'basic_app'
urlpatterns = [
path('register/', views.register, name='register'),
path('user_login/', views.user_login, name='user_login'),
]
views.py
def user_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user:
if user.is_active:
login(request, user)
return HttpResponseRedirect(reverse('index'))
else:
return HttpResponseRedirect("ACCOUNTS NOT ACTIVE")
else:
print("Someone tried to login and failed!")
print("Username: {} and password: {}".format(username, password))
return HttpResponse("Invalid login details supplied!")
else:
return render(request, 'basic_app/login.html', {})
login.html
{% extends 'basic_app/base.html' %}
{% block body_block %}
<div class="jumbotron">
<h1>Please Login!</h1>
<form method="post" action="{% url 'basic_app:user_login' %}">
{% csrf_token %}
<label for="username">Username:</label>
<input type="text" id="username" name="username" placeholder="Enter Username">
<label for="password">Password:</label>
<input type="password" id="password" name="password" placeholder="*******">
<input type="submit" name="" value="Login">
</form>
</div>
{% endblock %}
{#action="{% url 'basic_app:user_login' %}"#}
If I am not using action="{% url 'basic_app:user_login' %}" in <form > tag of login.html, nothing changes.
#Aditya Gupta
Please look this answer first ---->>>
Now in django normaly you must define action attribut when you want the view you specified on it receive some data. It recommanded to specify url of in action attribute of form.
Here is what i have in base.html (inside the footer, so this newsletter form will be in every page)
<form action="" method="POST">
{% csrf_token %}
<div class="form-group">
<div class="input-group mb-3">
<input type="text" class="form-control" placeholder='Enter email address' onfocus="this.placeholder = ''" onblur="this.placeholder = 'Enter email address'">
<div class="input-group-append">
<button class="btn" type="submit"><span class="lnr lnr-arrow-right"></span></button>
</div>
</div>
</div>
</form>
Here is the model (subscribe/models.py)
class Subscriber(models.Model):
email = models.EmailField()
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.email
what i have in views.py
def subscribe_form(request):
if request.method == 'POST':
email = request.POST.get('email')
new_email = Subscriber()
new_email.email = email
new_email.save()
return redirect('home-page')
here is urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.PostListView.as_view(), name='home-page'),
path('subscribe/', views.subscribe_form, name='subscriber'),
path('archive/', views.archive, name='archive-page'),
path('category/', views.category, name='category-page'),
path('contact/', views.contact, name='contact-page')
]
after submitting the submit button i'm getting this error in shell
Method Not Allowed (POST): /
Method Not Allowed: /
[18/Jan/2020 04:13:11] "POST / HTTP/1.1" 405 0
so, i'm a beginner, im trying to build a blog, but i didn't find any useful solution that can solve this issue. maybe i'm going totally wrong, but anyway if someone can help me to make this working.
Thank you all.
In your index URL, you are not allowed to post.So change it to subscribe/
<form action="{% url 'subscriber' %}" method="POST>
I am using a custom user model for my Django project and I can log in via /admin/ perfectly fine. But when I go to /accounts/login and try to log in, it just bounces me back to the login page without logging in. I am using django-registration-redux with the simple backend.
Via logging I discovered that the error happens in this method in django.contrib.auth.__init__.py:
def get_user(request):
"""
Returns the user model instance associated with the given request session.
If no user is retrieved an instance of `AnonymousUser` is returned.
"""
from .models import AnonymousUser
user = None
try:
#
# EXCEPTION THROWN ON BELOW LINE
#
user_id = _get_user_session_key(request)
backend_path = request.session[BACKEND_SESSION_KEY]
except KeyError:
pass
else:
if backend_path in settings.AUTHENTICATION_BACKENDS:
backend = load_backend(backend_path)
user = backend.get_user(user_id)
# Verify the session
if hasattr(user, 'get_session_auth_hash'):
session_hash = request.session.get(HASH_SESSION_KEY)
session_hash_verified = session_hash and constant_time_compare(
session_hash,
user.get_session_auth_hash()
)
if not session_hash_verified:
request.session.flush()
user = None
return user or AnonymousUser()
Any ideas? /accounts/register/ performs as expected, although I have overridden RegistrationView. Perhaps I have to do the same thing for logging in?
Login.html
{% extends "base.html" %}
{% load staticfiles %}
{% block body_block %}
<link href="{% static 'css/signin.css' %}" rel="stylesheet">
<div class="container">
<div class="jumbotron">
<h1 class="display-3" align="center">Login</h1>
</div>
<form method="post" action=".">
{% csrf_token %}
<h2 class="form-signin-heading">Please sign in</h2>
<label for="inputEmail" class="sr-only">Username</label>
<input type="text" name="email" id="id+username" class="form-control" placeholder="Username" required autofocus>
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" name="password" id="id_password" class="form-control" placeholder="Password" required>
<button class="btn btn-lg btn-primary btn-block" type="submit" value="Submit">Login</button>
</form>
Not a member?
Register
</div>
<p>
</p>
{% endblock %}
Urls.py
class MyRegistrationView(RegistrationView):
success_url = '/'
form_class = UserProfileRegistrationForm
def get(self, request, *args, **kwargs):
form = self.form_class(initial=self.initial)
return render(request, self.template_name, {'form': form})
def register(self, form):
logging.debug("THIS IS MY REGISTER")
new_user = form.save(commit=False)
new_user.set_password(form.cleaned_data['password1'])
new_user.save()
login(self.request, new_user)
logging.debug("Logged in")
signals.user_registered.send(sender=self.__class__,
user=new_user,
request=self.request)
logging.debug("After signals")
return new_user
urlpatterns = [
url(r'^', include('base.urls')),
url(r'^admin/', admin.site.urls),
url(r'^accounts/register/$', MyRegistrationView.as_view(), name="registration_register"),
url(r'^accounts/password/change/$', MyRegistrationView.as_view(), name="auth_password_change"),
url(r'^accounts/password/change/done/$', MyRegistrationView.as_view(), name="auth_password_changed"),
url(r'^accounts/', include('registration.backends.simple.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
EDIT:
I have a temporary fix of throwing a view into login in urls.py. Something tells me this is extremely dirty but it seems to work... for now. I'm open to better alternatives.
url(r'^accounts/login/$', my_view, name="login"),
def my_view(request):
if request.POST:
username = request.POST['email']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return render(request, 'index.html', {})
# Redirect to a success page.
else:
# Return an 'invalid login' error message.
pass
else:
return render(request, 'registration/login.html', {})
Try using {{ form }} in your login template, instead of rendering the fields manually. This can show whether the problem is in your template or elsewhere.
In this case, I think that the form fields should be username and password, not email and password as you have.
<input type="text" name="username" id="id_username" class="form-control" placeholder="Username" required autofocus>
<input type="password" name="password" id="id_password" class="form-control" placeholder="Password" required>