Я делаю страницу с информацией о пользователе.
В представлении я передаю request.user
, чтобы сформировать вот так
form = UserForm(request.POST, instance=request.user)
Проблема в том, что когда я сохраняю форму с помощью form.save()
, имя пользователя изменено, и я проверил self.isntance
. В UserForm
я обнаружил, что self.instance.username
в методе save()
изменен, но не в методе очистки поля (clean_username()
) и методе подкласса формы clean()
.
self.instance.username
изменяется только в методе save()
.
У меня есть другое поле с Usermodel, например поле электронной почты, но изменено только поле имени пользователя.
Любой совет или подсказка полезны для меня
пс. После того, как я написал этот вопрос, я обнаружил еще одну вещь, что self.instance
в методе save()
не является экземпляром исходного пользователя.
Это имя пользователя и адрес электронной почты - это данные request.POST.
Вот мой код
Посмотреть
@login_required(login_url='/member/login')
def change_user_info(request):
if request.method == 'POST':
form = UserForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.instance)
return redirect('/member/change-user-info')
else:
form = UserForm(instance=request.user)
context = {
'form': form,
'home_button': True
}
return render(request, 'member/user_info.html', context)
модель
class User(AbstractUser):
username = models.CharField(max_length=50, unique=True)
email = models.EmailField()
USERNAME_FIELD = 'username'
EMAIL_FIELD = 'email'
форма
class UserForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
field_list = ['username', 'email']
for field in field_list:
self.fields[field].required = False
new_password1 = forms.CharField(
required=False,
widget=forms.PasswordInput(
attrs = {
'autofocus': True,
'id': 'userinfo-new-password1',
'class': 'form-control',
'placeholder': '새 비밀번호',
'aria-describedby': 'newpassword1HelpBlock',
}),
)
new_password2 = forms.CharField(
required=False,
widget=forms.PasswordInput(
attrs = {
'autofocus': True,
'id': 'userinfo-new-password2',
'class': 'form-control',
'placeholder': '새 비밀번호 확인',
'aria-describedby': 'newpassword2HelpBlock',
}),
)
old_password = forms.CharField(
required=False,
widget=forms.PasswordInput(
attrs = {
'autofocus': True,
'id': 'userinfo-old-password',
'class': 'form-control',
'placeholder': '기존 비밀번호',
'aria-describedby': 'oldpasswordHelpBlock',
})
)
class Meta:
model = User
fields = [
'username',
'email',
]
widgets = {
'username': TextInput(attrs = {
# 'readonly': True,
'disabled': True,
'autofocus': True,
'id': 'disabledTextInput',
'class': 'form-control',
'aria-describedby': 'usernameHelpBlock',
}),
'email': EmailInput(attrs = {
'autofocus': True,
'id': 'userinfo-email',
'class': 'form-control',
'placeholder': 'EMAIL',
'aria-describedby': 'emailHelpBlock',
}),
}
def clean_username(self):
test = self.cleaned_data['username'] --> ''
test2 = self.instance.username --> has correct user name
return test
def clean_new_password1(self):
if not self.cleaned_data.get('new_password1'):
return None
return self.cleaned_data['new_password1']
def clean_new_password2(self):
if not self.cleaned_data.get('new_password2'):
return None
return self.cleaned_data['new_password2']
def clean_old_password(self):
password = self.cleaned_data.get('old_password')
if not self.instance.check_password(password):
raise forms.ValidationError('정보 변경을 위해서 기존 비밀번호를 입력해 주세요')
return password
def clean(self):
test = self.instance.username --> has correct username
super().clean()
new_password1 = self.cleaned_data.get('new_password1')
new_password2 = self.cleaned_data.get('new_password2')
if new_password1 and new_password2:
if new_password1 != new_password2:
raise forms.ValidationError(
"새 비밀번호가 일치하지 않습니다."
)
elif new_password1 is None and new_password2 is None:
pass
else:
raise forms.ValidationError(
"비밀번호 변경을 위해선 '새 비밀번호' '새 비밀번호 확인'란에 모두 입력하셔야 합니다."
)
def save(self, commit=True):
user = self.instance
username = self.instance.username --> ''
email = self.instance.email --> has correct email
if self.instance.email != self.cleaned_data.get('email'):
user.email = self.cleaned_data.get('email')
if self.cleaned_data['new_password2'] is not None:
user.set_password(self.cleaned_data.get('new_password2'))
user.save()
Спасибо
Поле вашего имени пользователя в форме отключено, поэтому вы получаете пустое значение в self.cleaned_data ['username'] в методе clean_username. Так что измените свой код, как показано ниже
def clean_username(self):
return self.cleaned_data['username'] or self.instance.username
Да, я понимаю это и это может быть одним из решений ~ !! Но я не могу понять, почему
self.instance
в методеsave()
заменен наrequest.POST
data. Даже я отменяю методsave()
. Я думаю, чтоself.instance
не следует менять раньшеself.instance.save()
в методеsave()
...