Django-модификация UserCreationForm
Моя проблема в том, что я пытаюсь изменить Django default UserCreationForm и его стандартные сообщения, но это не работает. Я также слышал, что некоторые проверки и начальные сообщения определяются отдельно и должны быть настроены отдельно, но я не нашел много информации об этом. Я пытался искать, но большинство из того, что я нашел, было либо старым и не работало для текущей версии django, либо изменяло только поля, но не сообщения об ошибках.
Я импортирую UserCreationForm в файл forms.py следующим образом:
from django.contrib.auth.forms import UserCreationForm
А затем я попытался изменить его следующим образом: Поля и все остальное полностью функционирует, только сообщения все еще по умолчанию, а не те, которые я пытался установить.
class UserSignUpForm(UserCreationForm):
username = forms.CharField(label="custom",
error_messages={'required': 'custom.',
'unique': 'custom.'})
password1 = forms.CharField(label="custom", widget=forms.PasswordInput,
error_messages={'required': 'custom.'})
password2 = forms.CharField(label="Potvrďte custom", widget=forms.PasswordInput,
error_messages={'required': 'custom.',
'password_mismatch': 'custom.'})
class Meta(UserCreationForm.Meta):
model = User
fields = UserCreationForm.Meta.fields
error_messages = {
'password_mismatch': {"password_mismatch": "custom"},
'password_too_short': {"password_too_short": "custom"},
'password_common': {"password_common": "custom"},
'password_entirely_numeric': {"password_entirely_numeric": "custom"},
}
Если кто-то знает, как решить эту проблему, пожалуйста, дайте мне знать. Я буду признателен за любые отзывы.
Для того чтобы вы могли перезаписать сообщение об ошибке с помощью атрибута Meta или поля формы error_messages
, ValidationError должен быть передан через ModelForm._update_errors
. Этого не происходит для ошибок, возникающих при проверке пароля - они добавляются напрямую, без дополнительных действий:
class BaseUserCreationForm(forms.ModelForm):
def _post_clean(self):
super()._post_clean()
# Validate the password after self.instance is updated with form data
# by super().
password = self.cleaned_data.get("password2")
if password:
try:
password_validation.validate_password(password, self.instance)
except ValidationError as error:
self.add_error("password2", error)
Переписать _post_clean
Одним из вариантов может быть перезапись метода _post_clean
для вызова _update_errors
вместо add_error
:
class UserSignUpForm(UserCreationForm):
...
class Meta(UserCreationForm.Meta):
...
error_messages = {
NON_FIELD_ERRORS: {
'password_mismatch': "custom mismatch",
'password_too_short': "custom too short",
'password_common': "custom common",
'password_entirely_numeric': "custom numeric",
"password_too_similar": "custom similar",
}
}
def _post_clean(self):
# Skip BaseUserCreationForm._post_clean:
super(forms.ModelForm, self)._post_clean()
# Validate the password after self.instance is updated with form data
# by super().
password = self.cleaned_data.get("password2")
if password:
try:
password_validation.validate_password(password, self.instance)
except ValidationError as error:
# Re-instantiate the ValidationError with an error_dict.
# Without this, the messages that _update_errors iterates
# over are strings (as returned by ValidationError.__iter__)
# instead of ValidationError instances. But we need
# ValidationError instances to know which error code to look for.
_error = ValidationError({NON_FIELD_ERRORS: error.error_list})
self._update_errors(_error)
Заменить сообщения об ошибках
В качестве альтернативы можно просмотреть form._errors
после завершения проверки и заменить сообщения об ошибках вручную:
password2 = forms.CharField(
label="Potvrďte custom",
widget=forms.PasswordInput,
error_messages={
"required": "custom.",
"password_too_similar": "foo",
"password_too_short": "bar",
},
)
def _post_clean(self):
super()._post_clean()
for field, error_list in self._errors.items():
if (
field == NON_FIELD_ERRORS
and self._meta.error_messages
and NON_FIELD_ERRORS in self._meta.error_messages
):
error_messages = self._meta.error_messages[NON_FIELD_ERRORS]
elif field in self.fields:
error_messages = self.fields[field].error_messages
else:
continue
for error in error_list.as_data():
if error.code in error_messages:
error.message = error_messages[error.code]
Обратите внимание, что ошибки проверки пароля добавляются в поле "password2" - поэтому вам нужно объявить свои собственные сообщения об ошибках, используя атрибут error_message
этого поля.
Второй вариант не пропускает BaseUserCreationForm._post_clean
, поэтому в конечном итоге он, вероятно, является более чистым решением.