NOTE: This question is asked in this SO post.
I applied the solution but its not working as expected. Maybe because I'm in Django 3.0?
Problem:
I am using an inlineformset_factory. I can modify the "child" form (aka formset) but not the "parent" form.
You can see an illustration of the problem here:
Here is following code so far:
# FORMS.PY
class Invoice_AJAX_Form(forms.ModelForm):
model = Invoice_AJAX
class Meta:
model = Invoice_AJAX
widgets = {
'ref_num': forms.TextInput(attrs={
'class': 'form-control',
}),
'customer': forms.TextInput(attrs={
'class': 'form-control',
})
}
class Invoice_Inventory_JAX_Form(forms.ModelForm):
class Meta:
model = Inventory_Invoice_AJAX
widgets = {
'price': forms.NumberInput(attrs={
'class': 'form-control cls_price',
'placeholder': 'Price',
}),
'inventory': forms.Select(attrs={
'class': 'form-control cls_inventory',
}),
'amount': forms.NumberInput(attrs={
'class': 'form-control cls_amount',
}),
'quantity': forms.NumberInput(attrs={
'class': 'form-control cls_quantity',
}),
'ref_num': forms.NumberInput(attrs={
'class': 'form-control',
}),
'discount': forms.NumberInput(attrs={
'class': 'form-control cls_discount',
})
}
form=Invoice_Inventory_JAX_Form, fields = '__all__', can_delete = False)
inventory_AJAX_formset = inlineformset_factory(Invoice_AJAX, Inventory_Invoice_AJAX, form=Invoice_Inventory_JAX_Form, fields = '__all__', can_delete = False)
# MODEL.PY
class Invoice_AJAX(models.Model):
ref_num = models.CharField(max_length=100)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, default=1)
date = models.DateField(default=datetime.date.today(), null=True, blank=True)
def __str__(self):
return str(self.ref_num)
class Inventory_AJAX(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=9, decimal_places=2)
invoice = models.ForeignKey(Invoice_AJAX, on_delete=models.CASCADE)
def __str__(self):
return self.name
class Inventory_Invoice_AJAX(models.Model):
inventory = models.ForeignKey(Inventory_AJAX, on_delete=models.CASCADE)
invoice = models.ForeignKey(Invoice_AJAX, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=9, decimal_places=2, blank=True, null=True)
quantity = models.DecimalField(max_digits=9, decimal_places=2, blank=True, null=True)
discount = models.DecimalField(max_digits=9, decimal_places=2, blank=True, null=True)
amount = models.DecimalField(max_digits=9, decimal_places=2, blank=True, null=True)
def __str__(self):
return self.invoice
# VIEWS.PY
class Invoice_AJAX_CreateView(CreateView):
model = Invoice_AJAX
fields = '__all__'
#form_class= Invoice_AJAX_Form
def get_context_data(self, *args, **kwargs):
context = super(Invoice_AJAX_CreateView, self).get_context_data(*args, **kwargs)
if self.request.POST:
context['track_formset'] = inventory_AJAX_formset(self.request.POST)
else:
context['track_formset'] = inventory_AJAX_formset()
return context
def form_valid(self, form):
context = self.get_context_data(form=form)
formset = context['track_formset']
if formset.is_valid():
response = super().form_valid(form)
formset.instance = self.object
formset.save()
return response
else:
return super().form_invalid(form)
The solution on the post I referred above is
You need to set the form_class in your View, instead of fields.
However, if I do that (uncomment the line above in the code, it gives me an error of
ModelForm has no model class specified.
And it points out to this line:
context = super(Invoice_AJAX_CreateView, self).get_context_data(*args, **kwargs)
Is there a way around this?