Django: невозможно войти в систему пользователю с правильным email/паролем
Я очень новичок в Django и это мой первый проект. Я пытаюсь создать простую систему входа/регистрации с MySQL в качестве базы данных и пользовательской моделью пользователя. Пользователь успешно регистрируется, но не может войти, используя правильный pw и email.
Я попробовал переделать мою функцию регистрации и индексную функцию (login) и изменил имя пользователя на email в моей пользовательской модели и индексной функции.
view.py:
from django.shortcuts import render, redirect
from django.contrib.auth import login, logout, authenticate
from django.shortcuts import render, redirect
from .models import CustomUser
from .forms import CustomUserCreationForm, EmailAuthenticationForm
from django.contrib.auth.forms import AuthenticationForm
from .backends import EmailBackend
# sign up
def signup(request):
if request.user.is_authenticated:
# if user is already logged in, redirect to the appropriate page
return redirect('/home')
if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
user = form.save(commit=True)
# Hash the password
user.set_password(user.password)
user.save()
else:
form = CustomUserCreationForm()
return render(request, 'signup.html', {'form': form})
# login
def index(request):
if request.method == 'POST':
form = EmailAuthenticationForm(data=request.POST)
if form.is_valid():
email = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = EmailBackend().authenticate(request, email=email, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
return redirect('error')
else:
form = EmailAuthenticationForm()
return render(request, 'index.html', {'form': form})
forms.py:
from django import forms
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from .models import CustomUser
# custom sign up form
class CustomUserCreationForm(UserCreationForm):
first_name = forms.CharField(widget=forms.TextInput(attrs={'autofocus':'autofocus'}))
email = forms.EmailField()
class Meta(UserCreationForm):
editable = True
model = CustomUser
fields = ('first_name', 'last_name', 'email')
# custom login form:
class EmailAuthenticationForm(AuthenticationForm):
username = forms.EmailField(widget=forms.EmailInput(attrs={'autofocus': True}))
# clean username function to make sure the username is an email
def clean_username(self):
username = self.cleaned_data.get('username')
try:
CustomUser.objects.get(email=username)
return username
except CustomUser.DoesNotExist:
models.py:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
# custom user model to include extra fields:
class CustomUser(AbstractBaseUser):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField(unique=True, max_length=255)
is_staff = models.BooleanField(default=False)
# keeps track of whether the account was confirmed or not thgough email confirmation
is_active = models.BooleanField(default=True)
REQUIRED_FIELDS = ['first_name', 'last_name']
USERNAME_FIELD = 'email'
# changed the default manager to the custom manager for login
@classmethod
def get__by_natural_key(cls, email):
return cls.objects.get(email=email)
backends.py:
from django.contrib.auth.backends import BaseBackend
from django.contrib.auth.models import User
from .models import CustomUser
class EmailBackend(BaseBackend):
def authenticate(self, request, email=None, password=None, **kwargs):
try:
user = CustomUser.objects.get(email=email)
except CustomUser.DoesNotExist:
return None
if user.check_password(password):
return user
def get_user(self, user_id):
try:
return CustomUser.objects.get(pk=user_id)
except CustomUser.DoesNotExist:
return None
Все похожие сообщения, которые я нашел, касались сотрудников или администраторов.
<1>> уже хэширует функцию, вы здесь хэшируете ее во второй раз. Таким образом, вы подписываетесь под:UserCreationForm
def signup(request):
if request.user.is_authenticated:
# if user is already logged in, redirect to the appropriate page
return redirect('/home')
if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
user = form.save()
return redirect('name-of-some-view')
else:
form = CustomUserCreationForm()
В вашей функции EmailBackend.authenticate я вижу, что вы загружаете пользователя и проверяете его пароль, но я не вижу функции login() перед возвратом пользователя. Может ли это быть недостающим элементом?
Вот документация Django, объясняющая процесс входа пользователя в систему для объекта django.contrib.auth.models.User: https://docs.djangoproject.com/en/4.1/topics/auth/default/#how-to-log-a-user-in