Я пытался создать адрес электронной почты для входа / аутентификации в views.py, но он возвращает «пользователь - нет». Я пытался использовать только электронную почту для входа в систему, а не имя пользователя. Если я попытался войти с электронной почтой, кажется, что пользователь «Нет» с пользовательскими сообщениями об ошибках «недействительные учетные данные» в views.py.
Django версия: 3.0.4 // Модель: пользовательский пользователь Model (AbstractBaseUser) -> USERNAME_FIELD = 'email' // Backend: ModelBackend -> использовать электронную почту для имени пользователя
Проблема 1: определение входа во Views.py возвращает 'user is None' // Проблема 2: модель имеет пароль (по умолчанию), пароль1 и пароль2 (оба определены UserCreationForm)
- users_models.py
from django.conf import settings
from django.contrib.auth import authenticate
from django.contrib.auth.models import AbstractBaseUser
from django.db import models
from django import forms
from django.utils import timezone
from .users_managers import UserManager
class 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 forms
from django.contrib.auth import authenticate, get_user_model
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from .users_models import User
class 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 user
class 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_model
from django.contrib.auth.backends import ModelBackend
# from django.contrib.auth.models import check_password
from django.contrib.auth.hashers import check_password
class 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',
]
логин. 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 forms
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.template import loader
from django.contrib import auth, admin
from django.contrib.auth import login, authenticate
from django.contrib.auth.models import User, Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.redirects.models import Redirect
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponseRedirect
from django.apps import AppConfig
from apps.users_forms import UserCreationForm, UserLoginForm, UserChangeForm
from apps.users_models import User
@csrf_exempt
def 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_exempt
def 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})
Как я могу решить эту проблему?