0

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:

https://www.dropbox.com/s/won84143o16njhr/dj007_inlineformsetfactory_unable_to_modify_primary_form.jpg?dl=0

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?

Ben
  • 25
  • 8
  • Typo: You use `:` instead of `=`, i.e. `model: Invoice_AJAX`, instead it needs to be `model= Invoice_AJAX`... – Abdul Aziz Barkat Jul 06 '21 at 15:25
  • Does this answer your question? [Use of colon in variable declaration](https://stackoverflow.com/questions/51639332/use-of-colon-in-variable-declaration) – Abdul Aziz Barkat Jul 06 '21 at 15:26
  • @AbdulAzizBarkat Thanks for the response. Yes its a typo sorry about that I was modifiying the code beforehand. That said, I still get the same result even if it is `model=Invoice_AJAX`. – Ben Jul 06 '21 at 16:19
  • You do need to set `form_class` as said in your linked question... – Abdul Aziz Barkat Jul 06 '21 at 16:22
  • Ah gotcha. Thanks for looking at again. Works now as expected. It turns out there were several instances of `:` and `=` when I look at it again and not only one. Fixed it + form_class declartion. Thanks! – Ben Jul 06 '21 at 16:25

0 Answers0