I'm Prety new in Django. After a few google search, I find full CRUD and I know how to handle that. But in User registration, I fell some problem all over the online every one uses Form.py to handle registration form but I don't want to use Form.py I like to customize it.
but the problem is when I use auth for login then Django auth says it's a wrong password
I use
authenticate(email=email,password=password)
for login check
Is anyone please explain custom login registration without using Form.py with some example.
Here is my View.py Code
def loginCheck(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 HttpResponse('Find User')
else:
return HttpResponse("Not Find User")
and my User Registration Code
def registration(request):
checkData = AuthUser.objects.filter(email=request.POST.get('email'))
if not checkData:
User.objects.create_user(
username=request.POST.get('username'),
email=request.POST.get('email'),
password=(request.POST.get('password')),
)
messages.add_message(request, messages.INFO, 'User Saved Successfully')
return redirect('loginView')
else:
messages.add_message(request, messages.INFO, 'Email Already Exists')
return redirect('loginView')
My Login code return Not Find User.
Try this minimal example. In this, you can create User and log in through API.
import json
from django.views.generic import View
from django.contrib.auth.models import User
from django.http import JsonResponse
from django.contrib.auth import authenticate, login
class UserRegisterView(View):
def get(self, request):
return JsonResponse({"message": "METHOD NOT ALLOWED"})
def post(self, request, *args, **kwargs):
json_body = json.loads(request.body)
username = json_body.get('username')
password = json_body.get('password')
email = json_body.get('email')
is_staff = json_body.get('is_staff', False)
is_superuser = json_body.get('is_superuser', False)
User.objects.create_user(
username=username, email=email,
password=password, is_staff=is_staff,
is_superuser=is_superuser
)
return JsonResponse({"message": "User created"})
class LoginView(View):
def get(self, request):
return JsonResponse({"message": "METHOD NOT ALLOWED"})
def post(self, request, *args, **kwargs):
'''
input data format:
{
"username" : "my username",
"password":"mysecret123#"
}
'''
json_body = json.loads(request.body)
username = json_body.get('username')
password = json_body.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return JsonResponse({"message": "login success"})
else:
return JsonResponse({"message": "login failed"})
Why I parsed request.body ?
How to receive json data using HTTP POST request in DJANGO
Reference:
How to authenticate user in DJANGO (official-doc)
UPDAYE-1
updated view as per the request,checking sufficent data in POST method (bold code)
def loginCheck(request):
if request.method == 'POST' and 'username' in request.POST and 'password' in request.POST:
username = request.POST.get('username'),
password = request.POST.get('password'),
user = authenticate(request, username=username, password=password)
if user is not None:
return HttpResponse('Find User')
else:
return HttpResponse("Not Find User")
return HttpResponse("POST data wrong")
If you want to your own registration process, you must use set_password function for saving password.
from django.contrib.auth.models import User
user = User.objects.get_or_create(username='john')
user.set_password('new password')
user.save()
Related
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)
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")
I create models,forms and views for registrarion and i want to create a login view so that after registration user can login.
models.py
from django.contrib.auth.models import AbstractUser
from django_countries.fields import CountryField
g_CHOICES = (('male','male'),('female','female'))
class User(AbstractUser):
gender = models.CharField(max_length=100,choices=g_CHOICES,default="male")
country = CountryField()
location = models.CharField(max_length=30, blank=True)
forms.py
g_CHOICES = (('male','male'),('female','female'))
class UserRegisterForm(UserCreationForm):
email = forms.EmailField()
gender = forms.ChoiceField(choices=g_CHOICES)
country = CountryField().formfield()
location = forms.CharField(max_length=30,)
class Meta:
model = User
fields = ['first_name','last_name','username','email',
'password1','password2','gender',
'country','location']
views.py
def register(request):
if request.method == 'POST':
rform = UserRegisterForm(request.POST)
if rform.is_valid():
rform.save()
username = rform.cleaned_data.get('username')
messages.success(request,('Account created for '+str(username)))
return redirect('/')
else:
rform = UserRegisterForm()
return render(request,'reg.html',{'rform':rform})
Now i want to create a view for login please someone help
You need a view that takes the user's username and password from the POST request, then authenticates them and logs them in using 'authenticate' and 'login' from django.contrib.auth package.
from django.contrib.auth import login, authenticate
from django.views import View
class HandleLogin(View):
def get(self, request):
return render(request, "login.html", {})
def post(self, request):
username= request.POST.get("username")
password = request.POST.get("password")
user = authenticate(username, password)
if user is not None:
if user.is_active:
login(request, user)
# Do something for succesfull logged in
else:
# Do something else because user is not active
else:
# Do something about user not existing
For more information: https://docs.djangoproject.com/en/2.2/topics/auth/default/
You can use something like below one:
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)
messages.success(request, 'You are now logged in')
return redirect('dashboard')
else:
messages.error(request, 'Invalid credentials')
return redirect('login')
else:
return render(request, 'accounts/login.html')
Or if you are using a django form you can do this way too and this is more preferred way:
def user_login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(request,
username=cd['username'],
password=cd['password'])
if user is not None:
login(request, user)
return HttpResponse('Authenticated '\
'successfully')
else:
return HttpResponse('Invalid login')
else:
form = LoginForm()
return render(request, 'account/login.html', {'form': form})
I have a custom user model. After doing successful login, I am getting the anonymous user in HttpResponseRedirect and templates as well. How do I get the logged in user?
Login View:
class LoginFormView(View):
form_class = UserLoginForm
user_model = get_user_model()
template_name = 'account/login.html'
def get(self, request, *args, **kwargs):
form = self.form_class
return render(request, self.template_name, {'form':form})
def post(self, request, *args, **kwargs):
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponseRedirect(reverse('home'))
else:
messages.error(request, 'Please enter correct email and password!')
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
If you have the request template context processor enabled, you'll be able to access the user in the template with {{ request.user}}.
Secondly, make sure you are importing the login function and not the login view. It should be:
from django.contrib.auth import login
The django usermodel django.contrib.auth.models.User has a field 'last_login' record the time when a user is successfully login.
But I donot see a code such as 'last_login=datetime.now()' in function from django.contrib.auth import login or from django.contrib.auth import authenticate. I also checked the django.contrib.auth.signals.user_logged_in.
where is the code for update the field 'last_login'?
Below is all the related source coede,how is the login process invoke the update_last_login? I don't see any code in login views or Authenticate function suoure code.
def update_last_login(sender, user, **kwargs):
"""
A signal receiver which updates the last_login date for
the user logging in.
"""
user.last_login = timezone.now()
user.save(update_fields=['last_login'])
user_logged_in.connect(update_last_login)
from django.dispatch import Signal
user_logged_in = Signal(providing_args=['request', 'user'])
#sensitive_post_parameters()
#csrf_protect
#never_cache
def login(request, template_name='registration/login.html',
redirect_field_name=REDIRECT_FIELD_NAME,
authentication_form=AuthenticationForm,
current_app=None, extra_context=None):
"""
Displays the login form and handles the login action.
"""
redirect_to = request.REQUEST.get(redirect_field_name, '')
if request.method == "POST":
form = authentication_form(request, data=request.POST)
if form.is_valid():
# Ensure the user-originating redirection url is safe.
if not is_safe_url(url=redirect_to, host=request.get_host()):
redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)
# Okay, security check complete. Log the user in.
auth_login(request, form.get_user())
return HttpResponseRedirect(redirect_to)
else:
form = authentication_form(request)
current_site = get_current_site(request)
context = {
'form': form,
redirect_field_name: redirect_to,
'site': current_site,
'site_name': current_site.name,
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context,
current_app=current_app)
class ModelBackend(object):
"""
Authenticates against settings.AUTH_USER_MODEL.
"""
def authenticate(self, username=None, password=None, **kwargs):
UserModel = get_user_model()
if username is None:
username = kwargs.get(UserModel.USERNAME_FIELD)
try:
user = UserModel._default_manager.get_by_natural_key(username)
if user.check_password(password):
return user
except UserModel.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a non-existing user (#20760).
UserModel().set_password(password)
user_logged_in signal is connected to django.contrib.auth.models.update_last_login function, it makes:
user.last_login = timezone.now()
user.save(update_fields=['last_login'])
I think the best way of doing this thing is
request_user, data = requests.get_parameters(request)
user = requests.get_user_by_username(data['username'])
update_last_login(None, user)
You can also get user for request object by doing following.
user = request.user
on djnago 1.11
add this class :
class IsAuthenticated(BasePermission):
"""
Allows access only to authenticated users.
"""
def has_permission(self, request, view):
if request.user and request.user.is_authenticated:
user = request.user
user.last_login = timezone.now()
user.save(update_fields=['last_login'])
return request.user and request.user.is_authenticated
on setting file change :
'DEFAULT_PERMISSION_CLASSES': (
# custom class
'IsAuthenticated',
),