OneToOneField错误

时间:2018-06-25 17:48:44

标签: python django

我正在处理用户注册表单,该表单由两个Django表单组成,即CustomUserForm和CompanyProfileForm(即ModelForm)。这些表单通过位于CompanyProfile模型中的OneToOneField连接,如下面的代码所示。

class CompanyProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
    companyName = models.CharField(max_length=200, blank=False)
    companyRegNum = models.CharField(max_length=30, blank=True)

下面是我的CompanyProfileForm

class CompanyProfileForm(ModelForm):
    # keywordsContainer = forms.CharField(widget=forms.HiddenInput(attrs={
    #     'id': 'keywordsContainer_id'
    # }))
    class Meta:
        model = CompanyProfile
        fields = '__all__'
        widgets = {
            'companyName': forms.TextInput(attrs={
                            'class': 'form-control',
                            'id': 'companyNameId',
                            'name': 'companyName',
                            'required': 'required',
                            'data-rule-required': 'true',
                            'data-msg-required': 'Please enter company name'
                        }),
            'companyRegNum': forms.TextInput(attrs={
                            'class': 'form-control',
                            'id': 'companyRegNumId',
                            'name': 'companyRegNum',
                            'required': 'required',
                            'data-rule-required': 'true',
                            'data-msg-required': 'Please enter company reg number'
                        }),
            'contactNumber': forms.TextInput(attrs={
                            'class': 'form-control input_field',
                            'id':'contactNum',
                            'name': 'contactNumber',
                            'required': 'required',
                            'data-rule-required': 'true',
                            'data-msg-required': 'Please enter contact number'
                        }),
            'address': forms.TextInput(attrs={
                            'class': 'form-control',
                            'id': 'addressId',
                            'name': 'address',
                            'required': 'required',
                            'data-rule-required': 'true',
                            'data-msg-required': 'Please enter the address'
                        }),
            'areaCode': forms.TextInput(attrs={
                            'class': 'form-control',
                            'id': 'areaCodeId',
                            'name': 'areaCode',
                            'required': 'required',
                            'data-rule-required': 'true',
                            'data-msg-required': 'Please enter the areaCode'
                        }),
            'deliveryEmails': forms.TextInput(attrs={
                            'class': 'form-control textInput',
                            'id': 'deliveryEmailId',
                            'name': 'deliveryEmails',
                            'required': 'required',
                            'data-rule-required': 'true',
                            'data-msg-required': 'Please enter the email address(s)'
                        }),
            'provinces': forms.Select(attrs={
                           'multiple': 'multiple',
                           'id': 'provinces'
                       }),
            'tenderCategory': forms.Select(attrs={
                           'multiple': 'multiple',
                           'id': 'catSelect'
                       }),
            'keywords': forms.Select(attrs={
                           'id': 'keywords_id'
                       }),
            'package': forms.HiddenInput(attrs={
                            'id': 'package_id'
                        }),
            'pymntMethod': forms.HiddenInput(attrs={
                            'id': 'pymntType',
                            'value': '3'
                        }),
            'termsAndConditions': forms.CheckboxInput(attrs={
                            'id': 'termsAndConditions'
                        })
        }

这是我的观点。

def subscribe_view(request, billing_cycle, pk):
    if request.method == 'POST':
        userRegForm = CustomUserForm(request.POST)
        companyForm = CompanyProfileForm(request.POST)
        print(companyForm)

        if userRegForm.is_valid() and companyForm.is_valid():
            user = userRegForm.save()
            compProfile = companyForm.save(commit=False)
            if compProfile.user_id is None:
                compProfile.user_id = user.id
            compProfile.save()
            return HttpResponseRedirect('/user_account/dashboard')
        else:
            return HttpResponseRedirect(request.path)
    else:
        package = Packages.objects.get(pk=pk)

        if billing_cycle == '1' or billing_cycle == '0':
            b_cycle = billing_cycle
        else:
            b_cycle = '0'

        userRegForm = CustomUserForm()
        companyProfileForm = CompanyProfileForm()
        companyProfileForm.fields["pymntMethod"].initial = 3
        companyProfileForm.fields["package"].initial = pk
        #companyProfileForm.fields["keywordsContainer"].initial = 'zzz'
        #companyProfileForm.fields["user"].initial = 0
        bankingDetailsForm = BankingDetailsForm()

        args = {'userRegForm': userRegForm,
                'package': package,
                'billing_cycle': b_cycle,
                'companyProfileForm': companyProfileForm,
                'bankingDetailsForm': bankingDetailsForm
        }
        args.update(csrf(request))
        return render(request, 'user_account/subscribe.html', args)

现在我的问题是,上面的CompanyProfile模型中的OneToOneField是必需的,因为它也充当导致此行出现问题的主键字段

if userRegForm.is_valid() and companyForm.is_valid():

在视图中

,因为CompanyProfileModel的OneToOneField必须等到用户被保存后才为OneToOneField赋值。因此,CompanyProfileForm始终为user = models.OneToOneField(User,on_delete = models.CASCADE,primary_key = True),因此会验证为false。

我该如何解决这个问题。

2 个答案:

答案 0 :(得分:0)

如何做这样的事情?

if request.method == 'POST':
        userRegForm = CustomUserForm(request.POST)
        companyForm = CompanyProfileForm(request.POST)
        print(companyForm)

        if userRegForm.is_valid():
            user = userRegForm.save()
        else:
            #take user to somewhere to fix this
            pass

        companyForm.user = user
        if companyForm.is_valid():
            compProfile = companyForm.save(commit=False)
            if compProfile.user_id is None:
                compProfile.user_id = user.id
            compProfile.save()
            return HttpResponseRedirect('/user_account/dashboard')
        else:
            #You might want to delete user if things dont go well.  
            return HttpResponseRedirect(request.path)

答案 1 :(得分:0)

您应该只从CompanyProfileForm中排除用户字段。您已经在保存时进行了设置,因此根本不需要表单。

class CompanyProfileForm(ModelForm):
    class Meta:
        model = CompanyProfile
        exclude = ('user',)