I have these two models, Invoice
which represents an invoice and Item
which represents the items on the invoice.
from django.db import models
# Create your models here.
class Invoice(models.Model):
vendor = models.CharField(max_length=200)
client = models.CharField(max_length=200)
number = models.CharField(max_length=200)
date = models.DateTimeField(max_length=200)
due_date = models.DateTimeField()
def __str__(self):
return "Invoice number: {}".format(self.number)
class Item(models.Model):
invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE)
description = models.TextField()
quantity = models.DecimalField(max_digits=19, decimal_places=2)
rate = models.DecimalField(max_digits=19, decimal_places=2)
amount = models.DecimalField(max_digits=19, decimal_places=2)
subtotal = models.DecimalField(max_digits=19, decimal_places=2)
tax = models.DecimalField(max_digits=19, decimal_places=2)
notes = models.TextField()
terms = models.TextField()
def __str__(self):
return "{}".format(self.description)
And these are the forms from which the information will be collected:
from django import forms
from .models import Invoice, Item
class InvoiceForm(forms.ModelForm):
class Meta:
model = Invoice
fields = ('vendor','client', 'number', 'date', 'due_date')
widgets = {
'date': forms.TextInput(attrs={'class':'datepicker'}),
'due_date': forms.TextInput(attrs={'class':'datepicker'}),
}
class ItemForm(forms.ModelForm):
class Meta:
model = Item
fields = ('description', 'quantity', 'rate', 'amount',
'subtotal', 'tax', 'notes', 'terms')
My question is how do I reference any of the fields in the template ItemForm
so that it captures the data?
Because at least InvoiceForm
I have no problems with it, it shows me. For example if I do this I have no problems:
<!-- Client -->
<div class="row">
<div class="input-field col s4">
<label for="{{ form.client.id_for_label }}">Client</label>
{{ form.client }}
</div>
<div class="input-field col s4 offset-s4">
<label for="{{ form.due_date.id_for_label }}">Due Date</label>
{{ form.due_date }}
</div>
</div>
But when trying to reference some field ItemForm
I don't know how it should be done. For example, if I want to show the field in the template description
, ItemForm
how should I do it? Because if I try something like this, it doesn't show me anything:
<div class="input-field col s5">
{{ form.description }}
</div>
This is my view, although I don't know how to connect both forms either, for now I'm only interested in at least that they are displayed correctly in the template:
def invoice_generator(request):
form = InvoiceForm
return render(request, 'invoiceapp/invoice_generator.html', {'form': form})
Maybe I'm misfocused or I'm getting complicated, but I really don't know how to proceed.
I appreciate your help.
In general, when you work with those kinds of relationships (
Autor/Libro
,Factura/Item
, etc.) what you should use isFormsets
that they help you work with multiple forms in the same view.In this case you can use a
InlineFormset
:And in your template
invoice_generator.html
:Some considerations:
form
The del parameterinlineformset_factory
is optional, I am using it because you have already defined your form.extra
ofinlineformset_factory
is used to indicate the amount ofitems
that you will have initially, that is, your invoice will appear with 4 forms forItem
.FormSets
and manually render the forms you have to define themanagement_form
({{ formset.management_form }}
)FormSets
and manually render the forms you have to indicate theid
for it to work correctly ({{ form.id }}
)I did it using a class based view:
And different forms for each model, and overriding the
get_context_data
class method: