CreateView attribute error: no object attribute on form_invalid

Hey,

For some reason, my CreateView throws an error upon form_invalid (but does save correctly when the form is valid).

For instance:

class ProduitCreateView(LoginRequiredMixin, CreateView):

    def post(self, request, *args, **kwargs):
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        fourprod_formset = FourProdFormSet(self.request.POST)
        cases_formset = CaseFormSet(self.request.POST)
        form_val = form.is_valid()
        fourprod_val = False
        case_val = cases_formset.is_valid()
        if (form_val and fourprod_val and case_val):
            return self.form_valid(form, fourprod_formset, cases_formset)
        else:
            return self.form_invalid(form, fourprod_formset, cases_formset)

    def form_invalid(self, form, formset_fourprod, formset_case):
        return self.render_to_response(self.get_context_data(form=form, formset_fourprod=formset_fourprod, formset_case=formset_case))


    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)     # throw error here

        if self.request.POST:
            ctx["form"] = ProduitForm(self.request.POST)
            ctx["formset_fourprod"] = FourProdFormSet(self.request.POST)
            ctx["formset_case"] = CaseFormSet(self.request.POST)
        else:
            ctx["form"] = ProduitForm()
            ctx["formset_fourprod"] = FourProdFormSet()
            ctx["formset_case"] = CaseFormSet()
        return ctx

But I’m creating the object - so no, my view doesn’t have a object already, since it hasn’t saved as it was invalid? THe call to super().get_context_data(**kwargs) fails.

EDIT: the traceback

Please post the full traceback you’re receiving.

Side note: It appears that you’re rendering multiple forms on the same page. Whenever doing so, I always recommend using a prefix with each form to ensure there’s no conflict between them.

Side note #2: The system-supplied Class-Based Generic Views are all designed around working with single objects. Trying to extend those CBVs to work well with multiple objects can be frustrating at times. I usually recommend not using them when creating more complex pages containing multiple forms/objects.

If you look at the post method of BaseCreateView, you’ll see that it sets self.object=None.

Since you’re overriding that method, you’ll need to add that line in your code.

2 Likes

Arrrrgh you are right, it does. And adding the line does fix the issue.

Thanks for the sidenotes. Didn’t know about the prefixes. As for the Generic vues, I was sort of hesitating as to whether or not I should use them (for that case). I guess that brings a vote in the no column.

Yes, in this case, my opinion is that they’re not a good fit. (I do find a lot of value in them in the “common case”, but once you venture outside that, not so much.)

1 Like