I'm making user-information page.
In the view I pass the request.user to form like this
form = UserForm(request.POST, instance=request.user)
The problem is when I save the form with form.save(), username is changed and I have checked self.isntance In UserForm than I found that the self.instance.username in the save()method is changed , but not in the field's clean method(clean_username()) and The form subclass’s clean()method.
self.instance.username is only changed in the save()method.
I have another field with Usermodel like email field, but only username field is changed.
Any advise or clue is good for me
ps. After I wrote this question, I found one more thing that self.instance in save()method is not the origin user instance.
It's username and email is request.POST data.
Here is my code
view
@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)
model
class User(AbstractUser):
username = models.CharField(max_length=50, unique=True)
email = models.EmailField()
USERNAME_FIELD = 'username'
EMAIL_FIELD = 'email'
form
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()
Thanks