Asaduzzaman Sohel
Asaduzzaman Sohel

Reputation: 588

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.

Upvotes: 0

Views: 502

Answers (3)

Darik AKI
Darik AKI

Reputation: 1

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) 

Upvotes: 0

Daniel Roseman
Daniel Roseman

Reputation: 599490

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

Upvotes: 1

shafikshaon
shafikshaon

Reputation: 6404

Change this line

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

to

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

Upvotes: 0

Related Questions