django login user, after successful login user stay on same page - django

I have to implement Login in django, But the login can be done at product purchase time, on creating comment, and so on.
Here i am redirecting user on Index page after login.
But i have to make user stay on same page from which(order, rating) page he is login.
How i can do this ?
Here what i have implemented:
def login_view(request):
if request.method=='POST':
form=UserLoginForm(request.POST or None)
if form.is_valid():
email = form.cleaned_data["email"]
password = form.cleaned_data["password"]
try:
user = Customer.objects.get(email=email)
if user.check_password(password) :
if user.is_active and user.is_customer:
if user.mobile_verified :
user = authenticate(username=user.email, password=password)
login(request, user)
if request.POST.get('card_data'):
for items in request.POST.get('card_data').split(","):
cart = Cart(user=user, product_id=items)
cart.save()
total_cart = user.card_user.count()
else:
total_cart = 0
messages.success(request, "Login successfully.")
responss = redirect("Peru:home")
responss.delete_cookie('add_card_token')
return responss
else:
messages.success(request,"Mobile number is not verified")
return redirect("Peru:home")
else :
messages.info(request, "Your account may not be activated")
return redirect("Peru:home")
else:
messages.error(request,"Email or Password does not match")
return redirect("Peru:home")
except Exception as e:
messages.error(request, "User may not exists !")
return redirect("Peru:home")
else:
return redirect("Peru:home", forms=form)
else:
return redirect('Peru:home')

You need to pass next URL in template and in login view check for next url.
In template:
Login
And in login view:
from django.utils.http import is_safe_url
def login(request):
redirect_to = request.POST.get('next', request.GET.get('next', ''))
# check form validity
# authenticate user
if redirect_to and is_safe_url(url=redirect_to, host=request.get_host()):
return redirect(redirect_to)
else:
return redirect('index')

Related

Any Possibility to put condition on Password Required in Django Custom Auth?

I want the registered user to log in with the Email or PhoneNumber and the Password first. If the user forgot the Password then there should be the possibility to log in with OTP bypassing the Password which would be provided via SMS on the User Phone Number. So Is there any possibility to achieve that?
Here are official docs where the password field is always required.
https://docs.djangoproject.com/en/4.0/topics/auth/customizing/#a-full-example
I know we can change the username to the email or for a phone number if we want but how do we put the condition to login with Password/Random OTP. So how we can achieve that? a suggestion would be appreciated. Thanks
You can make your own CustomLoginBackend as
from django.contrib.auth import get_user_model
class CustomLoginBackend(object):
def authenticate(self, request, email, password, otp):
User = get_user_model()
try:
user = User.objects.using(db_name).get(email=email)
except User.DoesNotExist:
return None
else:
if password is not None:
if getattr(user, 'is_active', False) and user.check_password(password):
return user
else:
if getattr(user, 'is_active', False) and user.otp == otp: #<-- otp included in user table
return user
return None
Then in your login views.
from django.contrib.auth import authenticate, login
from django.contrib import messages
def login_view(request):
if request.method == 'POST':
email = request.POST.get('email', None)
password = request.POST.get('password', None)
otp = request.POST.get('otp', None)
user = authenticate(request, email=email, password=password, otp=otp)
if user is not None:
login(request, user)
# redirect to a success page
return redirect('dashboard')
else:
if password is not None:
# return either email or password incorrect
messages.error(request, "Invalid Email or Password")
return redirect('login')
else:
# return invalid otp
messages.error(request, "Invalid OTP")
return redirect('login')
return render(request, 'login.html')
And at last don't forgot to add AUTHENTICATION_BACKENDS in your settings.py as
AUTHENTICATION_BACKENDS = ['path_to_your.CustomLoginBackend ',]
Yes we can do that using forced login here is an example how i have did this please have a look i have a profile which is one to one relation with user
def login_otp(request):
mobile = request.session['mobile']
context = {'mobile':mobile}
if request.method == 'POST':
otp = request.POST.get('otp')
profile = Profile.objects.filter(mobile=mobile).first()
if otp == profile.otp:
user = User.objects.get(id = profile.user.id)
login(request , user)
return redirect('cart')
else:
context = {'message' : 'Wrong OTP' , 'class' : 'danger','mobile':mobile }
return render(request,'login_otp.html' , context)
return render(request,'login_otp.html' , context)

prevent user to access login page in django when already logged in?

def admin_login(request):
if request.method == 'POST':
username = request.POST["username"]
password = request.POST["password"]
user = authenticate(request,username = username, password = password)
if user is not None:
if(user.is_superuser):
auth_login(request, user)
return redirect(reverse("dashboard"))
else:
messages.info(request, "invalid credentials")
return redirect(reverse("admin"))
return render(request,'login.html')
this is mylogin function for admin , how to prevent user to access login page once logged in?
You can check if the user who is requesting is authenticated and if so, you can redirect him to another page. You can check user if he is authenticated like this
if request.user.is_authenticated:
# redirect
so your view function will be like this
def admin_login(request):
if request.user.is_authenticated:
return redirect(reverse("admin"))
if request.method == 'POST':
username = request.POST["username"]
password = request.POST["password"]
user = authenticate(request,username = username, password = password)
if user is not None:
if(user.is_superuser):
auth_login(request, user)
return redirect(reverse("dashboard"))
else:
messages.info(request, "invalid credentials")
return redirect(reverse("admin"))
return render(request,'login.html')
do this in beginning of your login function
def user_login(request, *args, **kwargs):
if(request.user.is_authenticated):
print('user authenticated')
return HttpResponseRedirect('/')

Redirecting from the login page to signup page back to login page with the same parameters in the url in django

I may not have been descriptive in the title but what I want is that for example When a new user opens a page where login is required --> he is redirected to login page with the login url having a next parameter to the previous page.But as he is a new user he chooses to signup by clicking on a link on the login page which takes him to signup page ,now this is where the problem comes - The signup url gets no parameter and once user signs up he is automatically redirected to login page and after he logs in he is redirected to the index page instead of the page where login was required.
This is my login view for my customer user model:
def login(request):
if request.user.is_authenticated:
return redirect('/')
else:
if request.method == "POST":
email=request.POST['email']
password=request.POST['password']
user=auth.authenticate(email=email,password=password)
if user is not None:
auth.login(request, user)
next_page = request.POST['next']
if next_page != '':
return redirect(next_page)
else:
return redirect('/')
else:
messages.info(request,"Email Password didn't match")
next = request.POST['next']
if next != '':
login_url = reverse('login')
query_string = urlencode({'next': next})
url = '{}?{}'.format(login_url, query_string) # create the url
return redirect(url)
else:
return redirect('login')
else:
return render(request,"login.html")
And this is my signup view:
def signup(request):
if request.user.is_authenticated:
return redirect('/')
else:
if request.method == "POST":
first_name=request.POST['first_name']
email=request.POST['email']
password=request.POST['password']
cpassword=request.POST['cpassword']
if password==cpassword:
if User.objects.filter(email=email).exists():
messages.info(request,'Email already in use')
return redirect('signup')
else:
user=User.objects.create_user(first_name=first_name,email=email,password=password)
user.save();
return redirect('/login/')
else:
messages.info(request,'Passwords not matching')
return redirect('signup')
else:
return render(request,'signup.html')
So what I am wanting is that : The next paramter in login url is taken to the signup url and then taken back to the login url from where after logging in the user can be redirected to that next page.
I have been trying to find this out from a long time now but I wasnt able to find any solution so any help would be appreciated . Thanks

Getting error 'django.contrib.auth.models.User.DoesNotExist: User matching query does not exist'

A similar question has been asked before but after going through all of them I was not able to find any answer to fit my case.
I am using Django's built-in authentication system to authenticate and log in a user. The user uses a log in form on index form and is supposed to be then redirected to a different url.
However after I log in with a username and password that are both valid entries, I am not redirected to the next url as I should be, and I get this error:
django.contrib.auth.models.User.DoesNotExist: User matching query does not exist.
These are my import lines for authenticate, login, and then for User.
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
But I don't think the problem is there.
It can't find the user but I don't know why that could be, because I am creating a username in the form and a password so it should be present.
Here is my login code:
def index(request):
if request.method == 'POST':
print("Received POST")
form = LoginForm(request.POST)
if form.is_valid():
print("FORM is Valid")
# proceed with registration
username, pwd = request.POST.get("username", None), request.POST.get("password", None)
if not username or not pwd:
print("nobody around here")
return HttpResponse("Username or password not present")
user = User.objects.get(username=username)
if user:
user = authenticate(username=username, password=pwd)
else:
user = User.objects.create_user(username, username, pwd)
login(request, user)
return redirect("dashboard")
else:
print("FORM is NOT VALID")
template = loader.get_template('index.html')
context = {
'username': 'Ralf',
'form': form,
}
return HttpResponse(template.render(context, request=request))
else:
# load the template file
template = loader.get_template('index.html')
context = {
'username': 'Ralf',
'form': LoginForm(),
}
return HttpResponse(template.render(context, request=request))
EDIT: I tried using a try except block and now the page will not load the form:
Here is the code I used:
if form.is_valid():
print("FORM is Valid")
# proceed with registration
username, pwd = request.POST.get("username", None), request.POST.get("password", None)
if not username or not pwd:
print("nobody around here")
return HttpResponse("Username or password not present")
try:
user = User.objects.get(username=username)
user = authenticate(username=username, password=pwd)
except:
user = User.objects.create_user(username, username, pwd)
login(request, user)
return redirect("dashboard")

How to pass user information to other page in Django 3.0?

I am new Django i am creating a simple login page and wants to redirect to home page with user info as soon as user clicks login button in login form user should be redirected to the home page with username
def login1(req):
if req.method == 'POST':
user = ppl.objects.filter(username = req.POST['text'])
print(req.POST['text'])
pwd = ppl.objects.filter(pwd = req.POST['pass'])
print(req.POST['pass'])
if user and pwd:
return HttpResponseRedirect(reverse('home', {'u':user}))
else:
return render(req,'login.html',{'error':"username and password does not match"})
def login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
return redirect('home')
else:
return redirect('login')
else:
return render(request, 'login.html')
And in your home page template or any other template you can call {{ request.user.username }} to see the current logged in user