我能够成功更新三种表格中的任何一种。但是,我的问题是,如果更改密码表单为空,则会抛出错误(如密码太短,当前密码不正确等),不像其他表格,如果我保持不变,我不会收到错误。我该如何处理修复?我尝试设置request.POST or None
无效,但我的想法已经不多了。我也没有使用{{ form.as_p }}
,而是逐场进行。这可能是一个问题吗?
表格
forms.py
from django.contrib.auth.forms import PasswordChangeForm
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
widgets = {
'first_name': forms.TextInput(attrs={
'class': 'lnd-user__input',
'id': 'first_name',
'placeholder': 'First Name'}),
'last_name': forms.TextInput(attrs={
'class': 'lnd-user__input',
'id': 'last_name',
'placeholder': 'Last Name'}),
'email': forms.TextInput(attrs={
'class': 'lnd-user__input',
'id': 'email',
'placeholder': 'Email'}),
}
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('mobile',)
widgets = {
'mobile': forms.TextInput(attrs={
'class': 'lnd-user__input',
'id': 'mobile',
'placeholder': 'Phone Number'})
}
class MyPasswordChangeForm(PasswordChangeForm):
old_password = forms.CharField(
label=("Old password"),
required=False,
strip=False,
widget=forms.PasswordInput(attrs={
'class': 'lnd-user__input',
'id': 'new_password2',
'type': 'password',
'placeholder': 'Old Password'}),
)
new_password1 = forms.CharField(
label=("New password"),
required=False,
widget=forms.PasswordInput(attrs={
'class': 'lnd-user__input',
'id': 'new_password2',
'type': 'password',
'placeholder': 'Enter new Password'}),
strip=False,
help_text=password_validation.password_validators_help_text_html(),
)
new_password2 = forms.CharField(
label=("New password confirmation"),
required=False,
strip=False,
widget=forms.PasswordInput(attrs={
'class': 'lnd-user__input',
'id': 'new_password2',
'type': 'password',
'placeholder': 'Repeat new Password'}),
)
views.py
@login_required(login_url='/accounts/login/')
def user_settings(request):
if request.method == 'GET':
user = User.objects.get(id=request.user.id)
user_profile = UserProfile.objects.get(user=user)
user_form = UserForm(instance=user)
user_profile_form = UserProfileForm(instance=user_profile)
password_change_form = MyPasswordChangeForm(user)
context = {
'uform': user_form,
'pform': user_profile_form,
'pwdform': password_change_form,
'user': user}
return render(request, 'accounts/user_settings.html', context)
if request.method == 'POST':
user = User.objects.get(id=request.user.id)
user_profile = UserProfile.objects.get(user=user)
user_form = UserForm(request.POST or None, instance=user)
user_profile_form = UserProfileForm(request.POST or None, instance=user_profile)
password_change_form = MyPasswordChangeForm(user, request.POST or None, use_required_attribute=False)
print password_change_form.is_valid(), password_change_form.error_messages
if request.POST:
if user_form.is_valid() is True and user_profile_form.is_valid() is True:
user = user_form.save(commit=False)
user.save()
profile = user_profile_form.save(commit=False)
user = User.objects.get(id=request.user.id)
profile.user = user
profile.save()
if password_change_form.is_valid() is True:
user_pwd_form = password_change_form.save()
update_session_auth_hash(request, user) # Important!
user_pwd_form.save()
context = {
'uform': user_form,
'pform': user_profile_form,
'pwdform': password_change_form,
'user': user,
}
return render(request, 'accounts/user_settings.html', context)
答案 0 :(得分:0)
似乎您不希望密码表单验证失败,除非填写了某些字段但不是全部字段。然而,如果任何字段留空,则通过制作所需的字段django将无法通过验证。因此,您应该做的是创建所有表单字段required=False
,然后在密码表单中添加clean
方法,如下所示:
from django.core.exceptions import ValidationError
def clean(self):
data = super(MyPasswordChangeForm, self).clean()
# if django field validation already failed, don't do any more validation
# because the field values we need to check might not be present.
if self.errors:
return data
# you could do this a lot of different ways, some of them simpler probably...
fields = ('old_password', 'new_password1', 'new_password2')
for fn in fields:
# if any field contains data
if data[fn]:
for fn in fields:
# if any field does not contain data
if not data[fn]:
raise ValidationError("All fields must be filled in.")
break
return data
这样,如果用户未填写changepassword表单上的任何字段,则验证不会失败。然后,如果你想知道这个人是否真的想要更改密码,你必须在你的视图中做一些事情,如:
if form.cleaned_data['new_password1']:
# put code here to change the users password
请注意,我没有测试此代码,因此它可能不完美,但它应该非常接近您的需要。
在Django表单中,clean
方法是它们为您提供涉及多个字段的表单验证的钩子。例如,如果两个数字输入必须加起来为第三个数字,那是你要检查的地方。如果表单输入有任何问题,请引发ValidationError
异常,Django将在表单上显示验证错误。