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
- Make sure to pass an instance. Hence. Reference
context['formset'] = journal_entry_formset(self.request.POST, instance=self.object)
- 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 %}