[Answered ]-Django multiple ModelForms with the same model and ForeignKeys

2πŸ‘

βœ…

The problem here is that you are not using a formset for the answer forms. You should: not only are they less clumsy than instantiating four forms separately, they have a clean() method that is specifically meant for validation that goes across the child forms, rather than being per form. Something like this:

class AnswerFormSet(forms.models.BaseInlineFormSet):
     def clean(self):
        correct_count = sum([form.cleaned_data['is_correct'] for form in self.forms])
        if correct_count != 1:
            raise forms.ValidationError('Exactly one answer must be marked as correct')

And in the view you would do this:

def edit_question(request):
    AnswerFormset = forms.models.inlineformset_factory(
         Question, Answer, formset=AnswerFormSet, extra=4, max_num=4)
    if request.method == 'POST':
        question = Question()
        question_form = QuestionForm(request.POST, instance=question)
        answer_formset = AnswerFormset(request.POST, instance=question)
        # Check these separately to avoid short-circuiting
        question_valid = question_form.is_valid()
        answer_valid = answer_formset.is_valid()
        if question_valid and answer_valid:
            question_form.save()
            # No need to add new question as it was already set as the instance above
            answer_formset.save()
        # etc

0πŸ‘

One option is as under:

class Question(models.Model):
    question_text = models.TextField('Question', max_length=256)
    def validate_answers(obj):
     if obj.answerchoice_set.filter(is_correct=True).count()==1
       #All well
       return True
     else:
       #delete question and answers if you wish or request for change
       return False

But you should keep in mind that this will check if your answers are valid after everything is saved. And then if you want you may delete your questions or answers.

def edit_question(request):
  #your usual code
  return (HttpResponseRedirect(...) if question.validate_answers() else  HttpResponseRedirect(...))
πŸ‘€Arpit Agrawal

Leave a comment