1

ユーザーがアカウントを作成できるようにする Web アプリケーションがあり、そうすることで、カスタム UserProfile モデルと Address モデルに関連付けられた標準の Django User モデルからユーザー オブジェクトが作成されます。AddressForm と UserProfileForm の両方をサブクラス化する ContactInfoForm を使用して、ユーザーが住所とプロファイルを更新できるようにする HTML フォームを作成しました。次のように、どちらも ModelForms です。

class AddressForm(forms.ModelForm):
    class Meta:
        model = common_models.Address
        exclude = ('updated_dt','address_type','created_dt')

    def __init__(self,*args,**kwargs):
        super(AddressForm,self).__init__(*args,**kwargs)

    firstname = forms.CharField(max_length=100, min_length=1, error_messages={'required':'Please Enter First Name'})
    lastname = forms.CharField(max_length=100, min_length=1, error_messages={'required':'Please Enter Last Name'})
    address1 = forms.CharField(max_length=100, min_length=1, error_messages={'required':'Please Enter Address'})
    etc...

class UserProfileForm(forms.ModelForm): 
    class Meta:
        model = common_models.UserProfile
        exclude = ('created_dt','updated_dt','entity_active','profile_hash','user','address')

    account_type = forms.ChoiceField(choices=account_choices,widget=forms.Select(attrs={'id':'account_type_list'}),error_messages={'required':'Please Select Account Type'})
    name = forms.CharField(max_length=100, min_length=1, error_messages={'required':'Please Company Name'})
    supplier_type = forms.ModelChoiceField(queryset=common_models.SupplierTypeCode.objects.all(),required=False,widget=forms.Select(attrs={'id':'account_type_select'}))
    buyer_type = forms.ModelChoiceField(queryset=common_models.ClientTypeCode.objects.all(),widget=forms.Select(attrs={'id':'account_type_select'}),required=False)


class ContactInfoForm(AddressForm,UserProfileForm): 
    class Meta:
        model = common_models.User
        exclude = ('email','username',
           'password','last_login','date_joined')

    def __init__(self,user=None,request_post_data=None,*args,**kwargs):
        if not request_post_data:
                params = dict([tuple([k,v]) for k,v in user.get_profile().address.__dict__.items()] +
            [tuple([k,v]) for k,v in user.get_profile().__dict__.items()])
                super(ContactInfoForm,self).__init__(initial=params,*args,**kwargs)
            else:
                super(ContactInfoForm,self).__init__(request_post_data,instance=user)

さて、次の質問があります。

1) auth_user テーブルと共に、user_profile とアドレス テーブルの両方が更新されるように、ContactInfoForm を保存するにはどうすればよいですか? ContactInfoForm の保存機能をオーバーライドしてから、Address と UserProfile の保存機能を次のように呼び出してみました。

def save(self):
    address = AddressForm.save(self)
    profile = UserProfileForm.save(self)

ただし、self のインスタンスはユーザー オブジェクトであるため、これは機能しません。したがって、上記の関数はどちらもユーザー オブジェクトを返します。

2) ContactInfoForm のinitメソッドの実装は、ユーザーが最初に連絡先情報の更新ページにアクセスしたときに HTML フォームに事前入力する最良の方法ですか? つまり、params ディクショナリの構築とそれを初期引数として使用することは正しいですか。このビューは login_required デコレータの背後にあるため、request.user からユーザー オブジェクトにアクセスできます。

3)私が達成しようとしていることを達成するためのより良い方法はありますか?

4

1 に答える 1

2

通常、Django では、3 つの個別のフォームを作成し、それらすべてを 1 つのビューで処理することによって、このようなことが行われています。

address_form = AddressForm(request.POST)
profile_form = UserProfileForm(request.POST)
contacts_form = ContactInfoForm(request.POST)
if address_form.is_valid() and profile_form.is_valid() and contacts_form.is_valid():
    address_form.save()
    profile_form.save()
    contacts_form.save()

このように少しコードが増えるかもしれませんが、はるかに明確で読みやすいです。

于 2012-03-25T02:18:52.133 に答える