I am building an app that allows users to view posts. However, every time I try to log in if I do not set the LoginRequiredMixin the user will still be able to view posts after logging out. But when I set the LoginRequiredMixin everytime user puts info it keeps going back to main page and nothing happens.
my home/views.py
#login_required
def home(request):
posts = Post.objects.all()
context = {'posts':posts}
return render(request, 'home/home.html', context)
class PostListView(ListView):
model = Post
template_name = 'home/home.html' # <app>/<model>_<viewtype>.html
context_object_name = 'posts'
ordering = ['-date_posted']
my home/urls.py:
path('',views.PostListView.as_view(), name='home'),
my main/urls.py
urlpatterns=[
path('signup/',views.signup,name='signup'),
path('signin/',views.user_login, name='user_login'),
path('signout/', views.user_logout, name='user_logout'),
path('',views.main_page,name='main_page'),
path('edit/', views.edit_profile, name='edit_profile'),
path('', include('django.contrib.auth.urls')),
]
my main/views.py:
def main_page(request):
return render(request,'main/user_login.html')
#login_required
def user_logout(request):
logout(request)
return redirect('main:main_page')
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save()
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=user.username, password=raw_password)
return redirect('main:main_page')
else:
form = SignUpForm()
return render(request, 'main/signup.html', {'form': form})
def user_login(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:
return redirect(reverse('home:home'))
else:
messages.error(request,'Sorry, the username or password you entered is not valid please try again.')
return HttpResponseRedirect('/')
else:
form=AuthenticationForm()
return render(request, 'main/user_login.html', {"form":form})
int my settings.py I only have:
LOGIN_URL = 'main:main_page'
I have been working a lot on this and I cannot find how to fix this issue.
Thanks in advance!
I guess the authentication is failing. However here is some snippet you can try.
from django.shortcuts import render,redirect
from django.contrib.auth import login,logout
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.decorators import login_required
def loginView(request):
if request.method == 'POST':
# Authentication form is provided by django, it will parse username and password
# in the post request
form = AuthenticationForm(data=request.POST)
if form.is_valid():
user = form.get_user()
login(request, user)
return redirect('home:home')
else:
form = AuthenticationForm()
return render(request, 'main/user_login.html', context={'form': form})
#login_required
def logout_request(request):
logout(request)
return redirect('home:user_login')
In settings.py make sure you have following properties set:
LOGIN_URL = reverse_lazy('home:user_login')
LOGIN_REDIRECT_URL = reverse_lazy('home:home')
LOGOUT_REDIRECT_URL = reverse_lazy('home:user_login')
Note: If you are using custom made user(other than default user model provided by djnago) then make sure you have following property in settings.py set, otherwise AuthenticationForm won't work.
AUTH_USER_MODEL = 'AppName.YourCustomUserModel'
Related
I have a login-page set as my homepage, localhost/mysite. I can login and successfully be redirected to localhost/mysite/mainpage.
The issue is that I can bypass the login simply by just entering the path in the URL, for example; I navigate to the homepage where the login-form is, then I just add /mainpage to localhost/mysite/ which successfully loads localhost/mysite/mainpage.
As you could imagine, this is not great. Does anyone know what I did wrong here?
My view
def index(request):
if request.method == "POST":
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
messages.info(request, "OK")
return redirect('/mysite/mainpage')
else:
messages.error(request, "NOT OK")
form = AuthenticationForm()
return render(request, 'mysite/login.html', {"form":form})
My urls.py
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^mainpage/$', views.main),
]
You can use the #login_required decorator [Django-doc] on your main view. This will redirect to the path set by the LOGIN_URL setting [Django-doc] to log in the user:
# app/views.py
from django.contrib.auth.decorators import login_required
def index(request):
# …
#login_required
def main(request):
# …
and in the settings.py:
# settings.py
# …
LOGIN_URL = 'index'
# …
EDIT: You can omit the ?next= query parameter, by setting the redirect_field_name=… parameter to None:
#login_required(redirect_field_name=None)
def main(request):
# …
The login function is not working , after i call login , authenticated is set 'true' but after i redirect to 'main' view authenticated is set 'false'. How to keep the user logged in even after redirection?
class LoginForm(forms.Form):
user = forms.CharField()
password = forms.CharField()
def login(self):
try:
cred = users.objects.get(username = user)
if password==cred.password):
return (True, cred)
return (False, 'Invalid Password.')
except:
return (False, 'Not exist')
from django.contrib.auth import login as auth_login
def login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
valid, message = form.login()
if valid:
auth_login(request, message)
print(request.user.is_authenticated)
# this is not working
return redirect(main)
else:
return redirect(login)
form = LoginForm()
args = {'form': form}
return render(request, 'accounts/login.html', args)
def main(request):
print(request.user.is_authenticated)
You shouldn't write check your user credentials in form class. Do it in your login view. Example:
# views.py
from django.contrib.auth import authenticate, login
from django.urls import reverse
from django.shortcuts import redirect, render
def login_view(request): #changed_the name shouldn't be login
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data["username"]
password = form.cleaned_data["password"]
user = authenticate(username, password)
if user:
login(user)
return redirect(reverse("main"))
else:
return redirect(reverse("login"))
form = LoginForm()
args = {"form": form}
return render(request, 'accounts/login.html', args)
# urls.py
urlpatterns = [
path("login/", views.login_view, name="login"), # <-- really important
path("main/", views.main_view, name="main")
]
To summarize - to redirect to another page use redirect function. If you set name parameter in url of you view, you can reffer to this view using reverse. Also don't reinvent the wheel and write your own authentication function. Django provides: authenticate(username, password) and login(user) function.
I have created a simple app for file upload. Everything worked fine.Then I wanted to add simple login and now I have problems.
These are my views
def login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(username=cd['username'],password=cd['password'])
if user is not None:
if user is active:
login(request,user)
return HttpResponse('Authenticated successfully')
else:
return HttpResponse('Disabled account')
else:
return HttpResponse('Invalid login')
else:
form=LoginForm()
return render(request,'account/login.html',{'form': form})
def list(request):
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile=request.FILES['docfile'])
newdoc.save()
# Redirect to the document list after POST
return HttpResponseRedirect(reverse('list'))
else:
form = DocumentForm() # A empty, unbound form
# Load documents for the list page
documents = Document.objects.all()
# Render list page with the documents and the form
return render(request,'list.html',{'documents': documents, 'form': form})
This is fileupload/urls
from django.conf.urls import url
from fileupload.views import list
from fileupload.views import login
urlpatterns = [
url(r'^list/$', list, name='list'),
url(r'^login/$', login, name='login'),
]
My forms
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
class DocumentForm(forms.Form):
docfile = forms.FileField(label='Select a file')
When I go to
http://127.0.0.1:8000/fileupload/list/
everything works fine.
If I try
http://127.0.0.1:8000/login/
I got this
I am confused becuase template is getting data from one fun and not from the other.
How to debug this?
It's clear that you and list and login in the URL should go after http://127.0.0.1:8000/fileupload/
Try check http://127.0.0.1:8000/fileupload/login/
Read this docs https://docs.djangoproject.com/en/1.11/topics/http/urls/
I'm using the built in Django authentication application. By default it has no password complexity so I'm trying to enable that.
I did find this documentation: https://docs.djangoproject.com/en/1.11/topics/auth/passwords/#module-django.contrib.auth.password_validation
But it specifically calls out that validators aren't applied when a user is created so it's no help to me.
I would really love to see a github project that uses this authentication app so I can see how to properly use this in a project.
Here are my forms.py and views.py files:
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth import password_validation
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
class UserRegistrationForm(forms.ModelForm):
password = forms.CharField(label="Password", widget=forms.PasswordInput)
password2 = forms.CharField(label="Repeat Password", widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username', 'first_name', 'email')
def clean_password2(self):
cd = self.cleaned_data
if cd['password'] != cd['password2']:
raise forms.ValidationError('Passwords don\'t match.')
return cd['password2']
class UserEditForm(forms.ModelForm):
class Meta:
model = User
fields = {'first_name', 'last_name', 'email'}
views.py
from __future__ import unicode_literals
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login
from .forms import LoginForm, UserRegistrationForm, UserEditForm
from django.contrib.auth.decorators import login_required
from django.contrib import messages
def user_login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(username=cd['username'], password=cd['password'])
if user is not None:
if user.is_active:
login(request, user)
return HttpResponse('Authenticated successfully')
else:
return HttpResponse('Disabled account')
else:
return HttpResponse('Invalid login')
else:
form = LoginForm()
return render(request, 'login.html', {'user_form': form})
def register(request):
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
if user_form.is_valid():
# create a new user object but avoid saving it yet
new_user = user_form.save(commit=False)
# set the pw
new_user.set_password(user_form.cleaned_data['password'])
# save the user object
new_user.save()
cd = user_form.cleaned_data
user = authenticate(username=cd['username'], password=cd['password'])
login(request, user)
return redirect('/plans/new')
else:
user_form = UserRegistrationForm()
return render(request, 'registration/register.html', {'user_form': user_form})
#login_required
def edit(request):
if request.method == 'POST':
user_form = UserEditForm(instance=request.user, data=request.POST)
if user_form.is_valid():
user_form.save()
messages.success(request, 'Profile updated successfully')
return redirect('/plans')
else:
messages.error(request, 'Error updating profile.')
else:
user_form = UserEditForm(instance=request.user)
return render(request, 'registration/edit.html', {'user_form': user_form})
i make customizing user.
so i need to login with email.
user = authenticate(email=email, password=password) seems not working...
help me...
let me know of how to fix my views.py.
here is my view.
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login, logout
from django.core.urlresolvers import reverse
from django.shortcuts import render
from LanguageExchange.forms import UserCreationForm,UserChangeForm
def index(request):
context_dict = {'boldmessage': "Crunchy, creamy, cookie, candy, cupcake!"}
return render(request, 'LanguageExchange/index.html', context=context_dict)
def register(request):
# A boolean value for telling the template
# whether the registration was successful.
# Set to False initially. Code changes value to
# True when registration succeeds.
registered = False
if request.method == 'POST':
user_form = UserCreationForm(data=request.POST)
# change_form = UserChangeForm(data=request.POST)
# if the two forms are valid..
if user_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
#if change_form.is_valid():
# change = change_form.save()
# change.set_password(user.password)
# change.user = user
registered = True
else:
print(user_form.errors)
else:
user_form = UserCreationForm()
# change_form = UserChangeForm()
return render(request,
'LanguageExchange/register.html',
{'user_form': UserCreationForm,
'registered': registered})
def user_login(request):
if request.method == 'POST':
username = request.POST.get('email')
password = request.POST.get('password')
user = authenticate(email=email, password=password)
if user:
if user.is_active:
login(request, user)
return HttpResponseRedirect(reverse('index'))
else:
return HttpResponse("Your Rango account is disabled.")
else:
print("Invalid login details: {0}, {1}".format(email, password))
return HttpResponse("Invalid login details supplied.")
else:
return render(request, 'LanguageExchange/login.html', {})
let me know of how to fix my views.py.
delete
user.set_password(user.password)
in register;
change
user = authenticate(email=email, password=password)
to
user = authenticate(username=email, password=password)
in user_login.