1

我有一个允许用户创建帐户的 Web 应用程序,并在此过程中创建一个标准 Django 用户模型的用户对象,与自定义 UserProfile 模型以及地址模型相关联。我已经构建了一个 HTML 表单,它允许用户通过使用继承了 AddressForm 和 UserProfileForm 的 ContactInfoForm 来更新他们的地址和个人资料;两者都是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 和 address 表,以及 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 的?

4

1 回答 1

2

通常在 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()

也许这种方式代码更多,但更清晰易读。

于 2012-03-25T02:18:52.133 回答