1

わかりましたので、実際にこれを偶然解決しました。何が起こったのかを理解したいだけです。

ModelForm を拡張し、モデルとして UserProfile を使用する独自のユーザー登録フォーム BaseCreationForm があります。すべての検証メソッドは正常に機能していましたが、save メソッドが私を悲しませていました。ユーザーを作成しようとするたびに (ビューでプロファイルが作成され、これをリファクタリングする場合があります)、Django は「BaseCreationForm オブジェクトには属性が消去されたデータがありません」と通知します。

しかし、欲求不満とアイデアが不足しているとき、save() メソッドでユーザーを作成する前に単純な「print self」ステートメントを追加したところ、問題はなくなり、ユーザーは正常に作成されました。以下は、機能するいくつかの clean() メソッド、save() メソッド、および clean() と save() メソッドを呼び出すビューのスニペットです。

clean() メソッドは正常に動作します

#example clean methods, both work beautifully
def clean_email(self):
    email = self.cleaned_data["email"]
    if not email:
        raise forms.ValidationError(self.error_messages['no_email'])

    try:
        User.objects.get(email=email)
    except User.DoesNotExist:
        return email
    raise forms.ValidationError(self.error_messages['duplicate_email'])

def clean_password2(self):
    # Check that the two password entries match
    password1 = self.cleaned_data.get("password1")
    password2 = self.cleaned_data.get("password2")
    if password1 and password2 and password1 != password2:
        raise forms.ValidationError(
            self.error_messages['password_mismatch'])
    return password2

save() メソッド:

 #save method requiring wizardry
 def save(self, commit=True):
    #This line makes it work. When commented, the error appears
    print self
    ###  
    user = User.objects.create_user(
        username=self.cleaned_data.get("username"),
        first_name=self.cleaned_data["first_name"],
        last_name=self.cleaned_data["last_name"],
        email=self.cleaned_data["email"],
        )
    user.set_password(self.cleaned_data["password1"])
    if commit:
        user.save()
    return user

そしてビュー(いくつかのものは省略されています):

class RegistrationView(FormView):
    template_name = 'register.html'
    form_class = BaseCreationForm
    model = UserProfile
    success_url = '/account/login/'

    def form_valid(self, form):
        form                    = BaseCreationForm(self.request.POST,
                                                  self.request.FILES)
        user                    = form.save()
        profile                 = user.get_profile()
        profile.user_type       = form.cleaned_data['user_type']
        profile.title           = form.cleaned_data['title']
        profile.company_name    = form.cleaned_data['company_name']
        .
        .
        .
        profile.save()
        return super(RegistrationView, self).form_valid(form)
4

1 に答える 1

5

メソッド内でフォームを再インスタンス化するべきではありませんform_valid。これは、フォームがすでに有効で、実際にフォームがメソッドに渡されたときに呼び出されます。代わりにそれを使用する必要があります。

(実際のエラーは、まったく呼び出していないためであることに注意してください。ただしform.is_valid()、上記で述べたように、ビューが既に呼び出しているため、呼び出すべきではありません。)

于 2013-07-10T11:08:03.590 に答える