AndrewIngram / django-extra-views

Django's class-based generic views are awesome, let's have more of them.
MIT License
1.38k stars 172 forks source link

form_valid vs forms_valid #190

Closed AlekseiKhatkevich closed 4 years ago

AlekseiKhatkevich commented 5 years ago

Hello it took me 5 hours to find out that form_valid has to do nothing to the process. Instead we have brand new shiny form(s)_valid. I guess it should be documented somewhere probably...

def forms_valid(self, form, inlines): # people normally use form_valid """ If the form and formsets are valid, save the associated models. """ self.object = form.save() for formset in inlines: formset.save() return HttpResponseRedirect(self.get_success_url())

CleitonDeLima commented 4 years ago

In version 0.13 form_valid works now, correct?

sdolemelipone commented 4 years ago

Yes, form_valid() is now called during forms_valid(). It is documented in the (very short) changelog.

shawnngtq commented 3 years ago

@AlekseiKhatkevich @sdolemelipone

Would like to check with regards to get_context_data methods.

# Default Django CBV get_context_data
# When I print get_context_data in get_context_data and form_valid method, they return the same dictionary
class PersonCreateView(CreateView):
    ...
    def get_context_data(self, **kwargs):
        context = super(PersonCreateView, self).get_context_data(**kwargs)
        print(context)
        ...

    def form_valid(self, form):
        context = self.get_context_data()
        print(context) # same as get_context_data method context
        formset1 = context["fomset1"]
        if formset1.is_valid():
            ...
        ...
        return super(PersonCreateView, self).form_valid(form)

# django-extra-views
# When I print get_context_data here, I realized that the dictionary is different
class PersonCreateView(CreateView):
    inlines = [Formset1Inline, Formset2Inline, ]
    inlines_names = ["formset1", "formset2", ]
    ...
    def get_context_data(self, **kwargs):
        context = super(PersonCreateView, self).get_context_data(**kwargs)
        print(context)
        ...

    def forms_valid(self, form, inlines):
        context = self.get_context_data()
        print(context) # there is no formset1 and formset2 inside context
        ...

        # I was wondering what is the right method to valid individual formset?
        # Is it as follow? Is there a cleaner method such as getting key value method instead of indexing?
        # Because if I do inlines[0], the list order is very important
        formset1 = inlines[0]
        if formset1.is_valid():
            ...
        ...
        return super(PersonCreateView, self).form_valid(form)