简体   繁体   中英

Doesn't save data django Foreignkey model

I've two model. I would like to save data from ForeignKey model. I'm created a modelform and save with my main foreignkey model. But I got this error ValueError at /c/customer/1/ Cannot assign "'1'": "BillingData.customer" must be a "CustomerData" instance.

I created Django model form and hocked up with view.

models.py file

class CustomerData(models.Model):
    customer_name = models.CharField(max_length=100)
    customer_no = models.CharField(max_length=100, default='', blank=True)
    mobile_number = models.IntegerField()
    alternative_phone = models.IntegerField(null=True, blank=True)
    union_name = models.ForeignKey(UnionName, on_delete=models.SET_NULL, null=True)
    word_name = models.ForeignKey(UnionWordName, on_delete=models.SET_NULL, null=True)
    full_address = models.CharField(max_length=200, null=True, blank=True)
    create_date = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return '%s, Mobile: %s' % (self.customer_name, self.mobile_number)

    def get_absolute_url(self):
        return reverse('customer_data', kwargs={'pk': self.pk})


class BillingData(models.Model):
    bill_no = models.CharField(max_length=100, default='', blank=True)

    customer = models.ForeignKey(CustomerData, on_delete=models.CASCADE)
    sales_person = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True)
    customer_money = models.IntegerField()
    create_date = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return '%s %s' % (self.customer.customer_name, self.create_date.date())

    def get_absolute_url(self):
        return reverse('customers.views.BillingPage', kwargs={'pk': self.pk})

forms.py file

class BillCreateForms(forms.ModelForm):
    bill_no = forms.CharField(max_length=100)
    customer = forms.ChoiceField(choices=[(x.id, x.customer_name) for x in CustomerData.objects.all()])
    customer_money = forms.IntegerField()

    def save(self, commit=True):
        instance = super(BillCreateForms, self).save(commit=False)
        customer_pk = self.cleaned_data['customer']

        instance.customer = CustomerData.objects.get(pk=customer_pk)
        instance.save(commit)
        return instance

    class Meta:
        model = BillingData
        fields = ('bill_no', 'customer', 'customer_money',)

views.py file

class CustomerDataView(FormMixin, generic.DetailView):
    model = CustomerData
    form_class = BillCreateForms
    template_name = "customers/customerdata_detail.html"
    print(form_class)

    success_url = '/c/'

    def post(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return HttpResponseForbidden()
        form = self.get_form()
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

I expect data save with foreignkey relation data. But doesn't save here.

You can't fix this problem in the save method, because the error happens before it gets that far.

You should be using a ModelChoiceField, not a ChoiceField. Not only would this fix the problem, it would also let you remove your entire save method.

customer = forms.ModelChoiceField(queryset=CustomerData.objects.all())

Change this line

instance.customer = CustomerData.objects.get(pk=customer_pk)

to

instance.customer_id = CustomerData.objects.get(pk=customer_pk).pk

Model:

class Blog(models.Model):
    # ...
    pass

class Entry(models.Model):
    blog = models.ForeignKey(Blog, on_delete=models.CASCADE, null=True)

Set object

b = Blog.objects.get(id=1)
e = Entry.objects.get(id=234)
b.entry_set.add(e) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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