Skip to content
Advertisement

Formset Not Saving on UpdateView Django

I’m having problem on formset not saving on UpdateView. This has been discussed in several SO post, and so far I can summarized them to following

  1. Make sure to pass an instance. Hence. Reference

context['formset'] = journal_entry_formset(self.request.POST, instance=self.object)

  1. Override the POST method. Reference Another One

My UpdateView is an exact replica of my CreateView except for two changes above.

Here is my CreateView:

class JournalEntryUpdateView(UpdateView):
    model = JournalEntry
    template_name = 'add-journal-entry.html'
    success_url = reverse_lazy('index')
    form_class = JournalEntryForm

    def get_context_data(self, *args, **kwargs):
        context = super(JournalEntryUpdateView, self).get_context_data(*args, **kwargs)
        if self.request.POST:
            context['formset'] = journal_entry_formset(self.request.POST, instance=self.object)
        else:
            context['formset'] = journal_entry_formset(instance=self.object)
        return context

    def form_valid(self, form):
        context = self.get_context_data(form=form)
        formset = context['formset']
        if formset.is_valid():
            response = super().form_valid(form)
            formset.instance = self.object
            formset.save()
            return response
        else:
            return super().form_invalid(form)

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        formset = journal_entry_formset(self.request.POST, instance=self.object)
        print ("form:", form.is_valid() ) # True
        print ("formset:", formset.is_valid() ) # False
        print(formset.non_form_errors()) # No Entry
        print(formset.errors) # {'id': ['This field is required.']}
        
        if (form.is_valid() and formset.is_valid()):
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

When I click submit, the page just refreshes and nothing happens. (i.e. I don’t have that typical yellow error debug screen page).

I check the value in the database and nothing changes.

I did have a lead. The print(formset.errors) line produces a {'id': ['This field is required.']}

This is a bit confusing to me because AFAIK, the ID (I’m assuming the PK) is already automatically created in CreateView and so there’s no need for me to edit it in UpdateView.

I also search about it in SO but most of the answers are for the jinja template like this one

Is there a way around this?

Advertisement

Answer

Actually, the answer is already in the last link (i.e. jinja template). Just simply adding the hidden fields works as expected.

            {% for form in formset %}
                {% for hidden in form.hidden_fields %}
                    {{ hidden }}
                {% endfor %}
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement