Django Crispy Forms: Применяйте пользовательский атрибут заголовка к каждой ошибке
Ситуация
Чтобы внести ошибки в форму регистрации, я делаю некоторые проверки в чистых методах класса формы (например, clean_email() и т.д.) и вызываю form.add_error('attribute', 'error message'). Я отображаю свои формы с помощью django-crispy-forms, используя тег шаблона {% crisy form %}.
Я хочу установить пользовательские атрибуты заголовка для сообщений об ошибках, которые отображаются в тегах span.
Я бы предпочел иметь возможность сделать это в самой форме Django, если это возможно, но если есть другой способ, я открыт и для него.
Пример
Например, вместо...
<span id="error_1_id_password" class="invalid-feedback"><strong>Password must have an uppercase and a lowercase letter</strong></span>
<span title="Ошибка пароля 1" id="error_1_id_password" class="invalid-feedback"><strong>Password must have an uppercase and a lowercase letter</strong></span>
Я просмотрел некоторую документацию по FormHelper, но я не вижу никакого механизма, который позволил бы мне применять определенные title атрибуты к каждому сообщению об ошибке.
Текущая HTML-форма
HTML, который отображается для формы (обратите внимание, в частности, на теги span с ошибками):
Форма Django
class EmailAuthUserCreationForm(forms.Form):
first_name = forms.CharField(
label='First name',
required=True,
widget=forms.TextInput(attrs={
'placeholder': 'Your first name..',
})
)
last_name = forms.CharField(
label='Last name',
required=True,
widget=forms.TextInput(attrs={
'placeholder': 'Your last name..',
})
)
email = forms.EmailField(
label='School email',
required=True,
widget=forms.TextInput(attrs={
'placeholder': 'Your college/university email address..',
})
)
password = forms.CharField(
label='Create password',
required=True,
help_text='Must be 8-100 characters including an uppercase and lowercase character and a digit',
widget=forms.PasswordInput(attrs={
'placeholder': 'Enter password..',
})
)
password_confirm = forms.CharField(
label='Re-enter password',
required=True,
widget=forms.PasswordInput(attrs={
'placeholder': 'Repeat the password..'
})
)
role_choice = forms.CharField(
label='Choose role',
required=True,
widget=forms.Select(choices=APP_ROLES)
)
tos = forms.BooleanField(
label='Terms of Service',
required=True,
)
def clean_email(self):
if EmailAuthUser.objects.filter(email=self.cleaned_data['email'].lower()).exists():
self.add_error('email', 'An account with this email address already exists.')
def clean_password_confirm(self):
passwd1 = self.cleaned_data['password']
passwd2 = self.cleaned_data['password_confirm']
if passwd1 and passwd2:
# Check that passwords match
if passwd1 != passwd2:
self.add_error('password_confirm', 'The passwords do not match.')
# Check password requirements
if len(passwd1) < 8:
self.add_error('password', "Password must be 8-100 characters")
if not schema1.validate(passwd1):
self.add_error('password', "Password must have an uppercase and a lowercase letter")
if not schema2.validate(passwd1):
self.add_error('password' "Password must contain a digit and no spaces")
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_class='form-horizontal'
self.helper.label_class='col-25 fs-400 ff-sans-normal'
self.helper.field_class='col-75'
self.helper.form_tag = False
self.helper.layout = Layout(
Row(
Column('first_name')
),
Row(
Column('last_name')
),
Row(
Column('email')
),
Row(
Column('password')
),
Row(
Column('password_confirm')
),
Row(
Column('role_choice')
)
)