I have partially implemented the formsets + many to many relationship feature with an Invoice and Inventory Model.
My problem is the form does not show the available Inventory (even though they exist). See problem here: https://www.dropbox.com/s/mtqkfee2pisyh5a/dj005_formset_many_to_many_relationship_working.jpg?dl=0
Here is the working code:
# MODELS.PY
class Invoice_Test_M2M(models.Model):
id = models.BigAutoField(primary_key=True)
ref_num = models.CharField(max_length=100)
def __str__(self):
return self.ref_num
class Inventory_Test_M2M(models.Model):
id = models.BigAutoField(primary_key=True)
inventory_name = models.CharField(blank=True, max_length=100)
invoice = models.ManyToManyField('Invoice_Test_M2M', through= "Invoice_Inventory_Through")
def __str__(self):
return self.inventory_name
class Invoice_Inventory_Through(models.Model):
invoice = models.ForeignKey(Invoice_Test_M2M, on_delete=models.CASCADE)
inventory = models.ForeignKey(Inventory_Test_M2M, 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)
amount = models.DecimalField(max_digits=9, decimal_places=2, blank=True, null=True)
# FORMS.PY
Inventory_TestLineItem_M2M_Formset = inlineformset_factory(Invoice_Test_M2M, Invoice_Inventory_Through, fields = '__all__', exclude=[], can_delete=True)
# VIEWS.PY
class Invoice_M2M_CreateView(CreateView):
model = Invoice_Test_M2M
fields = '__all__'
def get_context_data(self, **kwargs):
context = super(Invoice_M2M_CreateView, self).get_context_data(**kwargs)
if self.request.POST:
context['track_formset'] = Inventory_TestLineItem_M2M_Formset(self.request.POST)
else:
context['track_formset'] = Inventory_TestLineItem_M2M_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)
Is there a way around this?
PS. INTERESTINGLY, if I just use a pseudo many to many MODEL (i.e. using a foreign field and not a many to many field). It works.
You can see it working here: https://www.dropbox.com/s/32x84k8roa88jvf/dj005_formset_many_to_many_relationship_working_B.jpg?dl=0
So why not use this method? The main reason is the M2M has a built-in API in showing its relevant members (i.e. Shows the inventories of a specific Invoice). In the method above, I am under the impression I have to do it manually.
P.P.S. Related Stackoverflow post. I already implemented the solutions but I still get the same problem:
pendant to inline formsets for many-to-many relations
Accessing Many to Many "through" relation fields in Formsets