#python #django #authentication
Вопрос:
Итак, у меня проблема. У меня есть форма входа в систему, но когда я пытаюсь войти, она пишет, что «» уже существует. Как это возможно?Если у пользователя есть учетная запись, это означает, что она будет существовать. Но почему я совершаю эту ошибку?
views.py
def login(request):
if request.method == 'POST':
form = LoginForm(request.POST, request.FILES)
print(form.errors)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(email=cd['email'], password=cd['password'])
if user is not None:
if user.is_active:
login(request, user)
return HttpResponse('Authenticated successfully')
else:
return HttpResponse('Disabled account')
else:
return HttpResponse('Invalid login')
else:
return HttpResponse('Form is not valid')
else:
form = LoginForm()
return render(request, 'account/login.html', {'form': form})
Я совершаю ошибку:
<ul class="errorlist"><li>email<ul class="errorlist"><li>User with this already exists.</li></ul></li></ul>
Форма для входа в систему
class LoginForm(ModelForm):
class Meta:
model = User
fields = ['email', 'password']
widgets = {
'email': EmailInput(attrs={
'class': 'form-email',
'placeholder': 'email'
}),
'password': PasswordInput(attrs={
'class': 'form-password',
'placeholder': 'password'
})
}
Модель пользователя
class User(models.Model):
CHOICES = (
('1', 'Author'),
('2', 'Customer'),
('3', 'Author and Customer')
)
first_name = models.CharField(max_length=64, blank=False, verbose_name='')
last_name = models.CharField(max_length=64, blank=False, verbose_name='')
patronymic = models.CharField(max_length=64, blank=False, verbose_name='')
age = models.PositiveSmallIntegerField(verbose_name='', blank=False)
email = models.EmailField(unique=True, max_length=128, blank=False, verbose_name='')
password = models.CharField(max_length=32, blank=False, verbose_name='')
role = models.CharField(max_length=32, choices=CHOICES, default='Customer')
about = models.TextField(max_length=512, verbose_name='', blank=True)
Ответ №1:
Когда a ModelForm
не instance
указан, это означает, что он используется для создания экземпляра, и, следовательно, когда is_valid
вызывается в вашей форме, он обнаруживает, что указанное вами имя пользователя уже существует, и, следовательно, возвращается False
. По этой причине форма, используемая для входа пользователя, должна быть обычным Form
классом.
Двигаясь дальше, Django уже предоставляет встроенную форму, которую можно использовать для аутентификации django.contrib.auth.forms.AuthenticationForm
[Django docs]. Глядя на вашу реализацию, у вас есть пользовательская модель пользователя с электронной почтой в качестве USERNAME_FIELD
? Он AuthenticationForm
достаточно универсален, чтобы справиться с этим, поэтому вы можете напрямую использовать его в своем представлении (или, если вы хотите настроить виджеты форм, которые вы можете унаследовать от него).
Если вы хотите установить атрибуты для виджетов, просто унаследуйте AuthenticationForm
их и установите в методе forms __init__
:
from django.contrib.auth.forms import AuthenticationForm
class LoginForm(AuthenticationForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].widget.attrs.update({'class': 'form-email', 'placeholder': 'email'})
self.fields['password'].widget.attrs.update({'class': 'form-password', 'placeholder': 'password'})
Затем используйте эту форму в своем представлении:
def login(request):
if request.method == 'POST':
form = LoginForm(request, request.POST, request.FILES)
print(form.errors)
if form.is_valid():
user = form.get_user()
if user is not None:
if user.is_active:
login(request, user)
return HttpResponse('Authenticated successfully')
else:
return HttpResponse('Disabled account')
else:
return HttpResponse('Invalid login')
else:
return HttpResponse('Form is not valid')
else:
form = LoginForm(request)
return render(request, 'account/login.html', {'form': form})
Комментарии:
1. как я могу это сделать без встроенного класса django? Потому что я знаю, как добавить стили в форму аутентификации
2. это все еще не работает, я не хочу использовать имя пользователя, мне нужна электронная почта
3. @Ihor Только имя поля в форме
username
, оно будет отображаться как электронное письмо в шаблон, потомуAuthenticationForm
что оно закодировано таким образом, что оно будет использоватьUSERNAME_FIELD
модель, которая установлена,AUTH_USER_MODEL
чтобы найти поле и изменить это поле в отношении этого. «Это не работает» — ты даже не пробовал?4. @Ihor Вы должны визуализировать его так, как
{{ form.username }}
если бы вы ранее визуализировали{{ form.email }}
(я предполагаю, что это так, поскольку вы не добавили свой шаблон в вопрос)5. о, да, извините, для меня немного необычно использовать встроенные методы. Я пробовал, и он все еще выдает мне сообщение «Форма недействительна».