Unable to create formset from model

I have the following models:

class Answer(models.Model):
    review = models.ForeignKey(Review,related_name='answer_review_assoc',blank=False,on_delete=models.PROTECT)
    question=models.OneToOneField(Question,related_name='answer_question_assoc',blank=False,on_delete=models.PROTECT)
    answer=models.CharField(max_length=250,blank=True,null=True)
    creation_date=models.DateTimeField(blank=False)
    last_update_date=models.DateTimeField(auto_now=True)
    created_by=models.ForeignKey(settings.AUTH_USER_MODEL, related_name='answers_created_by',on_delete=models.PROTECT)
    last_update_by=models.ForeignKey(settings.AUTH_USER_MODEL, related_name='answers_last_update_by',on_delete=models.PROTECT)
    class Meta:
        verbose_name_plural = "Answers"


class Question(models.Model):
    question_text=models.CharField(max_length=200,blank=False)
    question_choice_type=models.CharField(max_length=3, blank=False,choices=QUESTION_CHOICE_TYPE)
    mandatory=models.BooleanField(blank=True)
    creation_date=models.DateTimeField(blank=False)
    last_update_date=models.DateTimeField(auto_now=True)
    series_type=models.CharField(max_length=3,blank=True,null=True,choices = Series.get_choices_models()['series_type'])
    created_by=models.ForeignKey(settings.AUTH_USER_MODEL, related_name='questions_created_by',on_delete=models.PROTECT)
    last_update_by=models.ForeignKey(settings.AUTH_USER_MODEL, related_name='question_last_update_by',on_delete=models.PROTECT)
    choices=models.ManyToManyField(Choice,blank=True,related_name='question_choices_assoc')
    question_type=models.CharField(max_length=10, blank=False,choices=QUESTION_TYPE)

Form:

class AnswerForm(ModelForm):
    answer = forms.CharField(label='Answer Text',required=True,widget=forms.TextInput(attrs={'placeholder': 'Answer Text','class':'form-control'}))
    class Meta:
        model=Answer
        fields=['answer']

    def __init__(self, *args, **kwargs):
        super(AnswerForm, self).__init__(*args, **kwargs)
        # question_text=self.instance.question.question_text
        # print(question_text)

I want to create formset of Answer and initialize with some questions This is what I do:

q=Question.objects.filter(question_type='PL').first()
ansfs=formset_factory(AnswerForm)
fs=ansfs(initial=[].append({'question':q}))

Now what i want is to set the label of the answer field in AnswerForm to question_text coming from initial values.

But i am unable to access self.instance.question.question_text in __init__ method of AnswerForm .

models.Answer.Answer.question.RelatedObjectDoesNotExist: Answer has no question.

Please advise

Can this be achieved from the way I have made the models?

[].append(whatever) in Python adds an item to a list, but doesn’t return an updated list, so basically you’re passing nothing here. Instead, update your code to:

fs=ansfs(initial=[{'question':q}])

Thanks for the response , I changed that but it still does not work.

One more thing i noticed is this : When i initialise with one row of Question, 2 forms are created and not one. Its happening always, one extra form is created in the formset.

And when I print self.instance inside init I get the following:
Answer object (None)
Answer object (None)

A simple initial on form is also not working:
f=AnswerForm(initial={'question':q})
f.instance returns

<Answer: Answer object (None)>

Regarding the extra form, in the formset documentation page, it states in part:

By default, formset_factory() defines one extra form;

So that behavior is defined and expected. If you don’t want the blank form included, set extra=0 in your formset_factory call.

ansfs = formset_factory(AnswerForm, extra=0)

Thanks Ken, that resolved the issue of extra form getting created, but i am still not able to access question object inside init method by self.instance.question, and self.instance prints
Answer object (None)

Ok, I’m a bit confused about what all you’re trying to do here. Just a couple of observations -

  • AnswerForm is a ModelForm, but ansfs is created from formset_factory, not modelformset_factory. (Regular formsets aren’t bound to model instances)

  • ansfs is a formset created from AnswerForm, which specifies Answer as the base model, yet you’re trying to pass a Question as the initial object.

  • As documented in the ModelForm page, the initial parameter overrides the values of the attached model fields.

If I understand what you’re really trying to get to (Now what i want is to set the label of the answer field in AnswerForm to question_text coming from initial values.), I’d take a step back and work this through incrementally - first build your formset from the answers, then work on attaching the question text as labels in the formset.

Thanks actually modelformset resolved the issue. Thanks for your help!!