1

我有一个用户个人资料,并希望允许用户更新关于他自己的所有信息(用户名、密码、姓名和其他信息)。使用下面的代码,不会加载 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))

更新:谢谢丹尼尔罗斯曼!现在我遇到了密码1和密码2字段的问题。他们没有被加载。

4

3 回答 3

1

这是一个常见错误:您已经覆盖了表单__init__方法的签名,因此第一个参数是current_user. 因此,当您在 POST 块中使用 实例化表单时UserProfileForm(request.POST, instance=user_profile),数据字典将用于 current_user 参数,而实际数据参数为空。因为是空的,所以表单没有绑定,所以没有错误。

覆盖表单的最佳方法__init__是从argsor获取任何新参数kwargs

def __init__(self, *args, **kwargs):
    current_user = kwargs.pop('current_user')
    super(UserProfileForm, self).__init__(*args, **kwargs)
    etc.
于 2012-06-08T08:27:26.093 回答
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."))
于 2012-06-11T20:50:32.730 回答
0

它不应该只是视图定义中的 {'form':form, } 吗?然后在模板中使用 {{ form.as_p }}

于 2012-06-08T08:04:28.763 回答