Об отключении автозаполнения в UserCreationForm
Я долго искал решение в интернете и на этом сайте, но ничего не помогло. Проблема в том, что в любой форме регистрации, которую я делаю на Django, каждый раз, когда пользователь нажимает на поле имени пользователя или пароля, показывается список ранее введенных значений, а такое поведение нежелательно.
Сырым фактом является то, что если я напрямую закомментирую эту строку
widget=forms.PasswordInput(attrs={'autocomplete': 'new-password'}),
в
# UserCreationForm, auth/form
password1 = forms.CharField(
label=_("Password"),
strip=False,
#widget=forms.PasswordInput(attrs={'autocomplete': 'new-password'}),
help_text=password_validation.password_validators_help_text_html(),
)
все работает так, как я хочу, включая имя пользователя.
Но я не хочу трогать Django UserCreationForm в auth/forms. Идеальным вариантом было бы создать подкласс и настроить его. Вот что я сделал
class CustomUserCreationForm(UserCreationForm):
def __init__(self, *args, **kwargs):
super(CustomUserCreationForm, self).__init__(*args, **kwargs)
# prevents the form to automatically autofocus
self.fields['email'].widget.attrs.pop("autofocus")
self.fields['username'].widget.attrs.pop("autocomplete")
#self.fields['password1'].widget.attrs.pop("autocomplete")
#self.fields['password1'].widget.attrs.update({'autocomplete':'off', 'maxlength':'32'})
...
Я пробовал его со многими комбинациями, в том числе с new-password, off, None, или даже с пустыми строками, все игнорируется.
Повторяю, единственный способ не автозаполнять поля имени пользователя и пароля - это закомментировать строку виджета в оригинальном классе, но это будет очень плохая идея и, особенно, она будет ломаться каждый раз, когда я буду обновлять Django.
Есть другие разумные решения?
Однажды у меня была форма регистрации, с которой я хотел добиться такого же поведения... Мне помогло, например, следующее:
forms.py
class RegistrationForm(forms.Form):
username = forms.CharField(widget=forms.TextInput(attrs={..., 'autocomplete': 'new-password'}))
email= forms.EmailField(widget=forms.EmailInput(attrs={..., 'autocomplete': 'new-password'}))
password = forms.CharField(widget=forms.PasswordInput(attrs={..., 'autocomplete': 'new-password'}))
# Setting the autocomplete='off' from within the form class by using {'autocomplete': 'new-password'} to remove the suggested list over/below the input field
В вашем случае, вероятно, вы могли бы попробовать...
class CustomUserCreationForm(UserCreationForm):
def __init__(self, *args, **kwargs):
super(CustomUserCreationForm, self).__init__(*args, **kwargs)
self.fields['username'].widget.attrs.update({'autocomplete': 'new-password'})
self.fields['email'].widget.attrs.update({'autocomplete': 'new-password'})
self.fields['password1'].widget.attrs.update({'autocomplete': 'new-password'})
Также обратите внимание, что вам придется добавить autocomplete="off" к тегу form также
<form method="POST" autocomplete="off">
...
...
</form>
Отказ от ответственности: В то время как поля имени пользователя и электронной почты больше не отображают предлагаемый список, поле пароля продолжает отображаться для многих людей. В моем случае так и было, поэтому в качестве обходного пути я изменил некоторые вещи на следующие...
# Instead of a password field, I've changed it to a text field
# Setting onkeyup event that will replace the text to asterisks
password = forms.CharField(widget=forms.TextInput(attrs={'id': 'password', 'autocomplete': 'new-password', 'onkeyup': 'hideCharacters()'}))
Внутри файла html:
<form method="POST" autocomplete="off">
...
...
</form>
# This script can be within a javascript file or the html: up to you...
# Script to replace text from field to asterisk(s).
<script type="text/javascript">
function hideCharacters() {
var x = document.getElementById("password");
x.value = x.value.replace(/./g, "*");
}
</script>
В двух словах, это сделало работу для меня.