简体   繁体   English

如何在视图中设置ForeignKey值

[英]How can I set the ForeignKey value in the view

My User registration form contains a ForeignKeyField and I am trying to set the value of this ForeignKeyField in the view. 我的用户注册表单包含一个ForeignKeyField,并且我正在尝试在视图中设置此ForeignKeyField的值。 As can be seen in the code below, I am passing a parameter "pk" to the view and this parameter is for setting the ForeignKeyField value before the form is rendered, but this doesn't seem to work. 从下面的代码中可以看出,我向视图传递了一个参数“ pk”,该参数用于在呈现表单之前设置ForeignKeyField值,但这似乎不起作用。 After posting the form I get this error "(1048, "Column 'package_id' cannot be null")". 发布表单后,出现此错误“((1048,“ Column'package_id'不能为空”))。

Here is my View. 这是我的观点。

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

        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()

            selected_provinces = companyForm.cleaned_data['provinces']
            selected_cats = companyForm.cleaned_data['tenderCategory']
            selected_package = companyForm.cleaned_data['package']

            for province_item in selected_provinces:
                compProfile.provinces.add(province_item)

            for cat_item in selected_cats:
                compProfile.tenderCategory.add(cat_item)

            keyword_ids_str = companyForm.cleaned_data['keywordListItem']
            if keyword_ids_str is not '' or keyword_ids_str is not None:
                keyword_ids = keyword_ids_str.split(',')[:-1]
                for keyword_id in keyword_ids:
                    keywordObj = Keywords.objects.get(id=int(keyword_id.strip()))
                    compProfile.keywords.add(keywordObj)

            compProfile.package(selected_package)

            return HttpResponseRedirect('/user_account/dashboard')
        else:
            return HttpResponseRedirect(request.path)
    else:
        packageOption = Packages.objects.get(id=pk)

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

        userRegForm = CustomUserForm()
        companyProfileForm = CompanyProfileForm(initial={'package': packageOption.id})
        bankingDetailsForm = BankingDetailsForm()

        #companyProfileForm.fields["package"].initial = packageOption.id

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

Here is Model: 这是模型:

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)
    contactNumber = models.CharField(max_length=20, blank=False)
    address = models.CharField(max_length=300, blank=True)
    areaCode = models.CharField(max_length=10, blank=False)
    deliveryEmails = models.TextField(blank=True)   #this is the list of all the people chosen to recieve daily notification.
    tenderCategory = models.ManyToManyField(category, blank=False)    #links the user to the chosen category.
    provinces = models.ManyToManyField(Province, blank=False)    #links the user to the chosen Provinces.
    package = models.ForeignKey(Packages, blank=False)       #links the user to the chosen package.
    pymntMethod = models.IntegerField(blank=True, default=3)   #this is the chosen payment method (e.g credit card=1, debit order=2 or direct debit=3)
    keywords = models.ManyToManyField(Keywords)     #links the user to the chosen keywords.
    extraKeywords = models.TextField(default='', blank=True)  #this field acts as a container of extra keywords from the user. These are keywords that we do not have in our database.
    termsAndConditions = models.BooleanField(blank=False, default=1)   #this is the T&C's field that must be agreed to by the client.
    commencementDate = models.DateTimeField(default=timezone.now, blank=True)

    def __str__(self):
        return self.companyName

Here is my form. 这是我的表格。

class CompanyProfileForm(ModelForm):
    provinces = forms.ModelMultipleChoiceField(queryset=Province.objects.all(), widget=forms.SelectMultiple(attrs={
        'id': 'provinces'
    }))

    tenderCategory = forms.ModelMultipleChoiceField(queryset=category.objects.all(), widget=forms.SelectMultiple(attrs={
        'id': 'catSelect'
    }))

    keywordListItem = forms.CharField(widget=forms.HiddenInput(attrs={
        'id': 'keywordListItem_id'
    }))

    class Meta:
        model = CompanyProfile
        exclude = (
            'user',
            'keywords',
            'commencementDate',
            'package',
        )
        fields = (
            'companyName',
            'companyRegNum',
            'contactNumber',
            'address',
            'areaCode',
            'deliveryEmails',
            'provinces',
            'tenderCategory',
            'termsAndConditions',
        )

        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)'
                        }),

            'package': forms.HiddenInput(),
            'pymntMethod': forms.HiddenInput(attrs={
                            'id': 'pymntType',
                            'value': '3'
                        }),
            'termsAndConditions': forms.CheckboxInput(attrs={
                            'id': 'termsAndConditions'
                        })
        }

does anybody know how to fix this error? 有谁知道如何解决此错误?

There's a few things that might be contributing to what you're running into: 有几件事可能会助您一臂之力:

  1. package is listed as a ForeignKey field that does not have null=True set, meaning it's a required field. package被列为没有设置null=TrueForeignKey字段,这意味着它是必填字段。 As such, there needs to be a value before the model instance is saved. 这样,在保存模型实例之前需要有一个值。 The reason setting a default attribute fixed that error is that you're now providing a value other than null for it. 设置default属性可修复该错误的原因是,您现在为其提供了非null的值。 If this is a field that can allow null, update the model to include null=True , and make sure to make a migration to update your database, then try this again. 如果这是一个可以允许为null的字段,请更新模型以使其包含null=True ,并确保进行迁移以更新数据库,然后重试此操作。

  2. When updating the package , I'm noticing that the package to be assigned is being passed to it like it's a method. 在更新package ,我注意到要分配的软件包像传递给它一样是一种方法。 I'm not aware that this is valid, since attributes are usually updated by direct assignment ( compProfile.package = selected_package ). 我不知道这是有效的,因为属性通常是通过直接分配( compProfile.package = selected_package )更新的。

  3. When updating the attribute for a model instance ( compProfile is a model instance of CompanyProfile ), any changes to that instance's attributes are not persisted to the database unless save() is called. 在更新模型实例的属性( compProfileCompanyProfile的模型实例)时,除非调用save()否则对该实例属性的任何更改都不会持久保存到数据库中。 This means that if it were fetched from the database later, the package would not match what was assigned. 这意味着,如果稍后从数据库中获取了该package ,则该package将与分配的package不匹配。 Make sure that compProfile.save() is called after modifying it. 确保修改后调用compProfile.save()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM