Authenticate with only username - django

I creating quiz app, in which user login with only username and the proceed for a quiz but django authenticate not working
views.py
class UserFormView(View):
form_class = UserForm
template_name = 'app/registration_form.html'
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False)
# cleaned data
username = form.cleaned_data['username']
user.save()
# autheticate
user = authenticate(username=username)
if user is not None:
if user.is_active:
login(request, user)
return redirect('app:quiz_list')
else:
return HttpResponse('active nahi hai')
else:
return HttpResponse('pehchan me nahi hai')
return render(request, self.template_name, {'form': form})

If you are using default authentication backend it requires username and password
You can create a custom authentication backend yourself by following related documentation
Considering you are not really authenticating you can just filter user from database and use login function afterwards
#TODO add exception if there is no user with username
user = User.objects.filter(username=username).get()
login(request, user)

Related

Django user.is active

Why when i desactive user on Django admin site in my class in post method
requirement return negative first if requirement user is not None ?
Probably if user desative true Django don`t look him in user table ?
class LoginView(View):
template_name = 'login.html'
def get(self, request):
form = LoginForm()
return render(request, self.template_name, locals())
def post(self, request):
form = LoginForm(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:
if user.is_active:
login(request, user)
return redirect('home')
else:
alert = messages.error(request, 'Twoje konto zostało zablokowane!')
return render(request, self.template_name, locals())
else:
alert = messages.error(request, 'Błędna nazwa użytkownika!')
return render(request, self.template_name, locals())
In authenticate function, django call authenticate on your AUTHENTICATION_BACKENDS in settings.py.
ModelBackend is a default authentication backend that has been provided by Django, and if you are using it, it checks if user is acive or not. It's sth like this:
def user_can_authenticate(self, user):
"""
Reject users with is_active=False. Custom user models that don't have
that attribute are allowed.
"""
is_active = getattr(user, 'is_active', None)
return is_active or is_active is None

want to remove error message in custom login form in django custom login

i don't want user have to see this message without any error i load page this come automatically here is my views.py
def my_login(request):
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data["username"]
password = form.cleaned_data["password"]
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('accounts:home')
else:
return HttpResponse('<h1>Page was found</h1>')
else:
return render(request, "login.html", {'form': form})
my forms.py
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
def clean(self, *args, **kwargs):
username = self.cleaned_data.get("username")
password = self.cleaned_data.get("password")
if username and password:
user = authenticate(username=username, password=password)
if not user:
raise forms.ValidationError("User does not exist.")
if not user.is_active:
raise forms.ValidationError("User is no longer active.")
return super(LoginForm, self).clean(*args, **kwargs)
You need to submit your form only when you receive a POST request.
def my_login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
# process form here
else:
form = LoginForm()
# send form to template
You will find more info about this in the documentation.

Django - How to allow registration only for predefined list of e-mails/usernames

I have a following simple view in my views.py for registration on my django site:
def register_user(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
user = authenticate(username=username, password=password)
login(request, user)
messages.succes(request, ('You have registered'))
return redirect('home')
else:
form = UserCreationForm()
context = {'form': form}
return render(request, 'register.html', context)
That approach would allow anyone to register but I want to allow only selected people to be able to register. I have a simple model for my database
class EmailList(models.Model):
email_addres = models.CharField(max_length=300, blank=True)
def __str__(self):
return self.email_addres
with some e-mail addreses (my site doesn't have usernames, your username is an email addres) and I want to allow registration only for email addresses that are in that database. How would I perform such check?
There is a functionality in Django that limits an access to users that pass a certain test: https://docs.djangoproject.com/en/3.2/topics/auth/default/#limiting-access-to-logged-in-users-that-pass-a-test
You need to create a test function (verifying that the user is in allowed users list), and then use user_passes_test decorator on the view. In case you are using class based views, you need to use a UserPassesTestMixin.
Assuming your code works properly, just grab the contents of the AllowedUsers model and check whether the username is in the queryset.
models.py
class AllowedUsers(models.Model):
allowed_email = models.EmailField(max_length=256)
def __str__(self):
return self.allowed_email
views.py
def register_user(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
object = form.save(commit=False)
allowed_emails = [user.allowed_email for user in AllowedUsers.objects.all()]
if object['username'] in allowed_emails:
form.save()
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
user = authenticate(username=username, password=password)
login(request, user)
messages.success(request, ('You have registered'))
return redirect('home')
else:
return redirect('/login/?next=%s' % request.path)
I should say that if it were me, I'd be doing this while overriding the form_valid method of the default LoginView
Alternative views.py
from django.contrib.auth import views as auth_views
from django.forms import ValidationError
class LoginView(auth_views.LoginView):
def form_valid(self, form):
allowed_emails = [user.allowed_email for user in AllowedUsers.objects.all()]
if form.cleaned_data['username'] in allowed_emails:
return super().form_valid(form)
else:
self.add_error('username', ValidationError("The provided username is not allowed"))

How can i create a login view after registration?

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})

Setting custom user object in context processor in django

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