Поле пароля в форме регистрации/логина не отображается должным образом | Django | HTML | Bootstrap
Я пытаюсь создать пользовательскую форму регистрации, используя HTML, CSS, Bootstrap как front end и Django как backend, когда я создаю форму, firstname, lastname и email отображаются как обязательные, но поля password и confirm_password не отображаются как обязательные, из forms.py, placeholder виджета и class=form-control также не применяются к нему.
Я спросил ChatGPT, он просит очистить кэш, переключиться на инкогнито или другой браузер, я попробовал все вещи, и все равно это появляется то же самое. Я предоставляю все файлы, связанные с формой регистрации, которую я создал.
- models.py
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db import models
class CustomUserManager(BaseUserManager):
def create_user(self, email, first_name, last_name=None, password=None, **extra_fields):
if not email:
raise ValueError('The Email field must be set.')
if not first_name:
raise ValueError('The First Name field must be set.')
if not password:
raise ValueError('Password cannot be left blank.')
email = self.normalize_email(email)
user = self.model(email=email, first_name=first_name, last_name=last_name, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
class CustomUser(AbstractBaseUser):
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50, blank=True, null=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = CustomUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name']
def __str__(self):
return self.email
- forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from .models import CustomUser
class SignUpForm(UserCreationForm):
class Meta:
model = CustomUser
fields = ['first_name', 'last_name', 'email', 'password1', 'password2']
widgets = {
'first_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter your first name'}),
'last_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter your last name'}),
'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Enter your email'}),
'password1': forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Enter password'}),
'password2': forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Confirm password'}),
}
- views.py
from django.shortcuts import render
from .forms import SignUpForm
def SignupView(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
return redirect('home')
else:
form = SignUpForm()
return render(request, 'signup.html', {'form': form})
def LoginView(request):
return render(request, 'login.html')
- signup.html
При выполнении указанного кода я получаю следующий результат для файла signup.html
введите описание изображения здесь
и следующий вывод, который я хочу получить:
введите описание изображения здесь
Обратите внимание на разницу в полях пароля и подтверждения пароля, это и есть проблема.
Форма модели BaseUserCreationForm
явно объявляет поля пароля (должна, потому что они не являются частью модели), и вы не можете использовать Meta.widgets, чтобы перезаписать виджет поля формы, которое было явно объявлено. Вы можете перезаписать только те поля, которые были неявно добавлены фабрикой форм модели.
(Да, я согласен, что это странно)
Поля, определенные декларативно, оставляются как есть, поэтому любые настройки, сделанные для мета-атрибутов, таких как виджеты, метки, help_texts или error_messages, игнорируются; они применяются только к полям, которые генерируются автоматически.
Ссылки: django docs и a related SO question
Если вы хотите установить свои собственные виджеты, вам придется объявить поля заново:
class SignUpForm(UserCreationForm):
password1 = forms.CharField(
label=_("Password"),
strip=False,
widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Enter password'}),
help_text=password_validation.password_validators_help_text_html(),
)
password2 = forms.CharField(
label=_("Password confirmation"),
widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Confirm password'}),
strip=False,
help_text=_("Enter the same password as before, for verification."),
)
class Meta:
model = CustomUser
fields = ['first_name', 'last_name', 'email', 'password1', 'password2']
widgets = {
'first_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter your first name'}),
'last_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter your last name'}),
'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Enter your email'}),
}
forms.py
необходимо обновить до следующего:
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import CustomUser
class SignUpForm(UserCreationForm):
class Meta:
model = CustomUser
fields = ['first_name', 'last_name', 'email', 'password1', 'password2']
widgets = {
'first_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'First name'}),
'last_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Last name'}),
'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email'}),
}
def __init__(self, *args, **kwargs):
super(SignUpForm, self).__init__(*args, **kwargs)
self.fields['password1'].widget.attrs['class'] = 'form-control'
self.fields['password1'].widget.attrs['placeholder'] = 'Password'
self.fields['password2'].widget.attrs['class'] = 'form-control'
self.fields['password2'].widget.attrs['placeholder'] = 'Confirm Password'
class LoginForm(forms.Form):
email = forms.EmailField(widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Enter your email'}))
password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Enter your password'}))
Включив функцию __init__
для класса SignupForm
, мы можем указать нужные атрибуты, чтобы получить требуемый результат.