[Fixed]-Django form returns is_valid() = False and no errors

23👍

That’s because you’re not “feeding” your form.

Do this:

invoicing_data_form = InvoicingDataForm(instance=invoice, data=request.POST or None)

11👍

You have an unbound form.
https://docs.djangoproject.com/en/1.7/ref/forms/api/#bound-and-unbound-forms

A Form instance is either bound to a set of data, or unbound.

If it’s bound to a set of data, it’s capable of validating that data and rendering the form as HTML with the data displayed in the HTML.

If it’s unbound, it cannot do validation (because there’s no data to validate!), but it can still render the blank form as HTML.

To bind data to a form, pass the data as a dictionary as the first parameter to your Form class constructor:

invoicing_data_form = InvoicingDataForm(request.POST or None, instance=invoice)

2👍

If you’re already giving request.POST to your form using request.POST or None, but it’s still invalid without errors, check that there isn’t any redirect going on. A redirect loses your POST data and your form will be invalid with no errors because it’s unbound.

👤Mark

1👍

I got this for AuthenticationForm which needs AuthenticationForm(None, request.POST) see Using AuthenticationForm in Django

0👍

I want to expand on the answer by @yuji-tomita-tomita

I typically use a CBV approach in Django, and how I’m handling forms:

def post(self, request, *args, **kwargs):
    form = self.get_form()
    if form.is_valid():
        # do things

Reading the source code I noticed that self.get_form() using get_form_kwargs(self) to populate the form with request.POST, thus getting bound to data. So if you’re overloading it like I did:

def get_form_kwargs(self):
    company = self.get_company()
    return {"company": company}

Make sure to call the super(), and it will finally work:

def get_form_kwargs(self):
    company = self.get_company()
    kwargs = super().get_form_kwargs()
    kwargs.update({"company": company})
    return kwargs

Leave a comment