我有一个用户个人资料,并希望允许用户更新有关他自己的一切(用户名,密码,姓名和其他信息)。使用下面的代码,不会加载password1和password2字段,也不会调用clean_username方法。要完成,当我调用is_valid方法时,它总是返回False但没有错误。
有人能帮帮我吗?谢谢。
#forms.py
class UserProfileForm(ModelForm):
c_user = None
error_messages = {
'duplicate_username': _("A user with that username already exists."),
'password_mismatch': _("The two password fields didn't match."),
}
username = forms.RegexField(label=_("Username"), max_length=30,
regex=r'^[\w.@+-]+$',
help_text = _("Required. 30 characters or fewer. Letters, digits and "
"@/./+/-/_ only."),
error_messages = {
'invalid': _("This value may contain only letters, numbers and "
"@/./+/-/_ characters.")})
def __init__(self, *args, **kwargs):
super(UserProfileForm, self).__init__(*args, **kwargs)
if kwargs.has_key('instance'):
current_user = kwargs.get('instance').user
self.c_user = current_user
self.password1 = forms.CharField(label=_("Password"),
widget=forms.PasswordInput, required = False)
self.password2 = forms.CharField(label=_("Password confirmation"),
widget=forms.PasswordInput, required = False,
help_text = _("Enter the same password as above, for verification."))
else:
self.password1 = forms.CharField(label=_("Password"),
widget=forms.PasswordInput)
self.password2 = forms.CharField(label=_("Password confirmation"),
widget=forms.PasswordInput,
help_text = _("Enter the same password as above, for verification."))
def clean_username(self):
# Since User.username is unique, this check is redundant,
# but it sets a nicer error message than the ORM. See #13147.
username = self.cleaned_data["username"]
if (self.c_user == None) or (self.c_user.username != username):
try:
User.objects.get(username=username)
except User.DoesNotExist:
return username
raise forms.ValidationError(self.error_messages['duplicate_username'])
def clean_password2(self):
password1 = self.cleaned_data.get("password1", "")
password2 = self.cleaned_data["password2"]
if password1 != password2:
raise forms.ValidationError(
self.error_messages['password_mismatch'])
return password2
class Meta:
model = UserProfile
exclude=('user')
>
#views.py
@csrf_protect
def update_user(request):
user = request.user
user_profile = user.get_profile()
if request.method == 'GET':
initials = {'username':user.username,
'email':user.email,
'name':user_profile.name,
'birth_date':user_profile.birth_date,
'weight':user_profile.weight,
'height':user_profile.height,
'smoke':user_profile.smoke,
'drink_alcohol':user_profile.drink_alcohol,
'alergies':user_profile.alergies,
}
form = UserProfileForm(initial=initials)
elif request.method == 'POST':
form = UserProfileForm(request.POST, instance=user_profile)
if form.is_valid():
f = form.save(commit=False)
user.username = request.POST.get('username')
user.save()
f.user = user
f.save()
print request.POST.get('username')
return redirect('/')
return render_to_response('profile.html', {'form':form}, context_instance=RequestContext(request))
更新:谢谢Daniel Roseman!现在我遇到的问题只有字段password1和password2。他们没有被装上。
答案 0 :(得分:1)
这是一个常见错误:您已覆盖表单__init__
方法的签名,因此第一个参数为current_user
。因此,当您在POST块中使用UserProfileForm(request.POST, instance=user_profile)
实例化表单时,将获取current_user参数的数据字典,并且实际数据参数为空。因为它是空的,所以表单没有绑定,所以没有错误。
覆盖表单__init__
的最佳方法是从args
或kwargs
获取任何新参数:
def __init__(self, *args, **kwargs):
current_user = kwargs.pop('current_user')
super(UserProfileForm, self).__init__(*args, **kwargs)
etc.
答案 1 :(得分:1)
试一试:
self.fields['password1'] = forms.CharField(label=_("Password"),
widget=forms.PasswordInput, required = False)
self.fields['password2'] = forms.CharField(label=_("Password confirmation"),
widget=forms.PasswordInput, required = False,
help_text = _("Enter the same password as above, for verification."))
答案 2 :(得分:0)
它不仅仅是视图def中的{'form':form,}。 然后在模板中使用{{form.as_p}}