I tried to make a email login/authenticate in views.py, but it returns 'user is None'.I tried to use just email for login not username.If I tried to login with email, it seems to take 'user is None' with custom error messages 'invalid credentials' in views.py.
Django version: 3.0.4 //Model: Custom User Model (AbstractBaseUser) -> USERNAME_FIELD = 'email' //Backend: ModelBackend -> use email for username
Problem 1: def signin in Views.py returns 'user is None' //Problem 2: model have a password(default), password1 and password2(both defined by UserCreationForm)
- users_models.py
from django.conf import settingsfrom django.contrib.auth import authenticatefrom django.contrib.auth.models import AbstractBaseUserfrom django.db import modelsfrom django import formsfrom django.utils import timezonefrom .users_managers import UserManagerclass User(AbstractBaseUser): USERNAME_FIELD = 'email' email = models.EmailField( verbose_name='email', max_length=255, db_index=True, unique=True, ) password1 = PasswordModelField('password', max_length=50, error_messages={something},) password2 = PasswordModelField('password check', max_length=50, error_messages={something},) ... objects = UserManager() class Meta: db_table = 'users' verbose_name = 'user' verbose_name_plural = 'users'
- users_forms.py
from django import formsfrom django.contrib.auth import authenticate, get_user_modelfrom django.contrib.auth.forms import ReadOnlyPasswordHashFieldfrom .users_models import Userclass UserCreationForm(forms.ModelForm): password1 = forms.CharField( label='password', strip=False, widget=forms.PasswordInput(attrs={'placeholder': 'something'}), error_messages={something}, ) password2 = forms.CharField( label='password check', widget=forms.PasswordInput, error_messages={something}, ) class Meta: model = User fields = ('email', 'password1', 'password2', ... ) ... def save(self, commit=True): user = super().save(commit=False) user.set_password(self.cleaned_data['password1']) # set_password if commit: user.save() return userclass UserLoginForm(forms.Form): email = forms.EmailField( label='email', max_length=255, widget=forms.TextInput(attrs={'autofocus': True}), ) password = forms.CharField( label='password', strip=False, widget=forms.PasswordInput, )
- backend.py
from django.contrib.auth import get_user_modelfrom django.contrib.auth.backends import ModelBackend# from django.contrib.auth.models import check_passwordfrom django.contrib.auth.hashers import check_passwordclass EmailBackend(ModelBackend): def authenticate(self, request, username=None, password=None): user_model = get_user_model() if '@' in username: kwargs = {'email': username} else: kwargs = {'username': username} try: user = user_model.objects.get(**kwargs) if user.check_password(password): return user else: return None except user_model.DoesNotExist: return None def get_user(self, id=None): user_model = get_user_model() try: return user_model.objects.get(pk=id) except user_model.DoesNotExist: return None
- settings.py
# AUTH_USER_MODEL = 'apps.User' # if I use this code, It returns errors. AUTHENTICATION_BACKENDS = ['apps.backend.EmailBackend','django.contrib.auth.backends.ModelBackend',]
- login.html
{% extends 'apps/base.html' %}{% load static %}{% block content %}<div class="container"><h1>login</h1> {% if error %}<p>{{ error }}</p> {% endif %}<form method="POST" action="{% url 'login' %}"> {% csrf_token %} {{ form.as_p }}<input type="submit" class="btn btn-primary" value="login"></form></div>{% endblock %}
- views.py
from django import formsfrom django.shortcuts import render, redirectfrom django.http import HttpResponsefrom django.template import loaderfrom django.contrib import auth, adminfrom django.contrib.auth import login, authenticatefrom django.contrib.auth.models import User, Groupfrom django.contrib.auth.admin import UserAdmin as BaseUserAdminfrom django.contrib.auth.forms import ReadOnlyPasswordHashFieldfrom django.contrib.redirects.models import Redirectfrom django.views.decorators.csrf import csrf_exemptfrom django.http import HttpResponseRedirectfrom django.apps import AppConfigfrom apps.users_forms import UserCreationForm, UserLoginForm, UserChangeFormfrom apps.users_models import User@csrf_exemptdef signup(request): if request.method == 'POST': creation_form = UserCreationForm(request.POST) if creation_form.is_valid(): creation_form.save() return redirect('index') else: creation_form = UserCreationForm() return render(request, 'signup.html', {'form': creation_form})@csrf_exemptdef signin(request): if request.user.is_authenticated: return redirect(reverse('index')) if request.method == "POST": login_form = UserLoginForm(request.POST) if login_form.is_valid(): username = login_form.cleaned_data['email'] # take email in form for username password = login_form.cleaned_data['password'] user = authenticate(username=username, password=password) if user is not None: # not going here !!! if user.is_active: login(request, user) return redirect('index') else: return render(request, 'login.html', {'form': login_form, 'error': 'invalid credentials'}) # errors here !!!!! always views.py returns this messages !!!!! else: login_form = UserLoginForm() return render(request, 'login.html', {'form': login_form})
How can I solve this problems?