def edit_morsel(request, morsel_id): morsel = get_object_or_404(Morsel.objects.prefetch_related('questions'), pk=morsel_id) if request.method == 'POST': if request.POST.get('action') == "+": extra = morsel.questions.all().count() + 1 request.session["extra"] = extra q = Question(morsel=morsel, question_text="") q.save() Answer(question=q, answer_text="").save() form = MorselCreationForm(initial=request.POST) formset = formset_factory( QuestionAnswerCreationForm, extra=extra, max_num=extra)(initial=[{ "question_text": request.POST.get("form-" + str(i) + "-question_text") if request.POST. get("form-" + str(i) + "-question_text") else "", "answer_text": request.POST.get("form-" + str(i) + "-answer_text") if request.POST. get("form-" + str(i) + "-answer_text") else "" } for i in range(extra)]) return render(request, 'app/edit_morsel.html', { 'form': form, 'formset': formset }) elif request.POST.get('action') == "-": extra = morsel.questions.all().count() - 1 request.session["extra"] = extra q = morsel.questions.all().last() q.delete() form = MorselCreationForm(initial=request.POST) formset = formset_factory( QuestionAnswerCreationForm, extra=extra, max_num=extra)(initial=[{ "question_text": request.POST.get("form-" + str(i) + "-question_text") if request.POST. get("form-" + str(i) + "-question_text") else "", "answer_text": request.POST.get("form-" + str(i) + "-answer_text") if request.POST. get("form-" + str(i) + "-answer_text") else "" } for i in range(extra)]) return render(request, 'app/edit_morsel.html', { 'form': form, 'formset': formset }) else: extra = int(request.session['extra']) form = MorselCreationForm(request.POST) formset = formset_factory(QuestionAnswerCreationForm, extra=extra)(request.POST) if form.is_valid() and formset.is_valid(): morsel.name = form.cleaned_data["name"] morsel.start_time = form.cleaned_data["start_time"] morsel.end_time = form.cleaned_data["end_time"] morsel.welcome_text = form.cleaned_data["welcome_text"] morsel.completed_text = form.cleaned_data["completed_text"] morsel.public_enabled = form.cleaned_data["public_enabled"] # this order is important to be able to access the relations for i, form in enumerate(formset): if morsel.questions: morsel.questions.all( )[i].question_text = form.cleaned_data["question_text"] morsel.questions.all( )[i].answer.answer_text = form.cleaned_data[ "answer_text"] morsel.questions.all()[i].save() morsel.questions.all()[i].answer.save() else: question = Question( question_text=form.cleaned_data["question_text"], morsel=morsel) answer = Answer( answer_text=form.cleaned_data["answer_text"], question=question) question.save() answer.save() morsel.save() form = MorselCreationForm( initial={ "start_time": morsel.start_time, "end_time": morsel.end_time, "name": morsel.name, "welcome_text": morsel.welcome_text, "completed_text": morsel.completed_text, "public_enabled": morsel.public_enabled }) request.session['extra'] = morsel.questions.all().count() initial_formset_values = [{ "question_text": question.question_text, "answer_text": question.answer.answer_text } for question in morsel.questions.select_related("answer").all()] formset = formset_factory( QuestionAnswerCreationForm, extra=1, max_num=len(morsel.questions.all()))(initial=initial_formset_values) return render(request, 'app/edit_morsel.html', { 'form': form, 'formset': formset })