我有一个Web应用程序,该应用程序允许用户创建一个帐户,并以此创建一个与标准Django User模型(与自定义UserProfile模型以及Address模型相关联)的用户对象。我建立了一个HTML表单,该表单允许用户通过使用ContactInfoForm来更新其地址和配置文件,该ContactInfoForm继承了AddressForm和UserProfileForm。两者都是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)如何保存ContactInfoForm,以便同时更新user_profile和地址表以及auth_user表?我尝试覆盖ContactInfoForm中的save函数,然后按如下所示调用Address和UserProfile的save函数:
def save(self):
address = AddressForm.save(self)
profile = UserProfileForm.save(self)
但是,由于self的实例是用户对象,因此该方法不起作用,因此上述两个函数都返回一个用户对象
2)当用户首次访问更新的联系信息页面时,我对ContactInfoForm的init方法的实现是否是预填充HTML表单的最佳方法?换句话说,构造params字典并将其用作初始参数是正确的。请记住,我可以从request.user访问用户对象,因为此视图位于login_required装饰器的后面。
3)也许有更好的方法来实现我要实现的目标,而不是变得更复杂且更Django / Pythonic?
最佳答案
通常在Django中,是通过创建3种不同的表单并将它们全部处理在一个视图中来完成的。
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()
也许这样可以编写更多代码,但是它更加清晰易读。