Please help am a beginner on django, i want to save my invoice in database, the problem i facing is when i want to save formset i cant peak foreign key from main form
View.py
def createInvoice(request):`
if request.method == 'GET':`
formset = LineItemForm(request.POST or None)`
form = InvoiceForm(request.GET or None)
if request.method == 'POST':
formset = LineItemForm(request.POST)
form = InvoiceForm(request.POST)
if form.is_valid():
invoice = Invoice.objects.create(customer = form.data["customer"],
customer_email = form.data["customer_email"],
message = form.data["message"],
date = form.data["date"],
due_date = form.data["due_date"],
)
if formset.is_valid():
for form in formset:
service = form.cleaned_data.get('service')
description = form.cleaned_data.get('description')
quantity = form.cleaned_data.get('quantity')
rate = form.cleaned_data.get('rate')
LineItem(customer=invoice,
service=service,
description=description,
quantity=quantity,
rate=rate,
amount=amount).save()
invoice.save()
return redirect('/')
context = {"title" : "Invoice Generator","formset":formset, "form": form}
return render(request, 'home/invoice.html', context)
Here is my Model.py
class Invoice(models.Model):
customer = models.CharField(max_length=100)
customer_email = models.EmailField(null=True, blank=True)
message = models.TextField(default= "this is a default message.")
date = models.DateField()
due_date = models.DateField()
def __str__(self):
return str(self.customer)
class LineItem(models.Model):
customer = models.ForeignKey(Invoice, on_delete=models.CASCADE)
service = models.TextField(max_length=100)
description = models.TextField(max_length=100)
quantity = models.IntegerField(max_length=10)
rate = models.DecimalField(max_digits=9, decimal_places=2)
amount = models.DecimalField(max_digits=9, decimal_places=2)
def __str__(self):
return str(self.customer)
This is my invoice create template without main form. Main form does not have any problem
invoce.html
<table class="table is-fullwidth is-bordered is-hoverable is-striped" id="table_field">
<thead>
<tr>
<th>Product/Service</th>
<th>Description</th>
<th>QTY</th>
<th>RATE</th>
<th>AMOUNT</th>
<th>ADD</th>
<th>REMOVE</th>
</tr>
</thead>
<tbody class="form-row">
<!--<input type="hidden" name="form-TOTAL_FORMS" value="1" id="id_form-TOTAL_FORMS"><input type="hidden" name="form-INITIAL_FORMS" value="0" id="id_form-INITIAL_FORMS"><input type="hidden" name="form-MIN_NUM_FORMS" value="0" id="id_form-MIN_NUM_FORMS"><input type="hidden" name="form-MAX_NUM_FORMS" value="1000" id="id_form-MAX_NUM_FORMS">
-->
<tr>
<td>{{formset.service}}</td>
<td>{{formset.description}}</td>
<td>{{formset.quantity}}</td>
<td>{{formset.rate}}</td>
<td>{{formset.amount}}</td>
<td><div class="input-group-append">
<button name="add" class="button is-small btn btn-success add-form-row" id="add" value="Add">+</button>
</div>
</td>
<td>
<div class="input-group-append">
<button name="remove" class="button is-small btn btn-danger remove-form-row" id="remove" value="Remove">-</button>
</div>
</td>
</tr>
</tbody>
</table>
When i try to save i get this error
Traceback (most recent call last):
File "C:\Users\xxxxxxx\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\xxxxxxx\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "D:\DS\Accounts\MyApp\views.py", line 136, in createInvoice
invoice.save()
UnboundLocalError: local variable 'invoice' referenced before assignment
I can't test it but I think you need different intentations.
invoice
is created only when if form.is_valid():
gives True
but you use invoice
in next if formset.is_valid():
which is run also when if form.is_valid():
is False
.
You should run if formset.is_valid():
inside if form.is_valid():
to use invoice
only when it was created
if form.is_valid():
invoice = Invoice.objects.create(customer = form.data["customer"],
customer_email = form.data["customer_email"],
message = form.data["message"],
date = form.data["date"],
due_date = form.data["due_date"],
)
if formset.is_valid():
for form in formset:
service = form.cleaned_data.get('service')
description = form.cleaned_data.get('description')
quantity = form.cleaned_data.get('quantity')
rate = form.cleaned_data.get('rate')
LineItem(customer=invoice,
service=service,
description=description,
quantity=quantity,
rate=rate,
amount=amount).save()
invoice.save()
return redirect('/')
@furas thank you for your response, when i try to format like you did nothing happen, but from your explanation i tried change my formset but still not working to
if formset.is_valid():
for form in formset:
service = form.cleaned_data.get('service')
description = form.cleaned_data.get('description')
quantity = form.cleaned_data.get('quantity')
rate = form.cleaned_data.get('rate')
amount = form.cleaned_data.get('amount')
LineItem(customer=invoice,
service=service,
description=description,
quantity=quantity,
rate=rate,
amount=amount).save()
invoice.save()
but still not working
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.