# Populating formset with a query

**URL:** <https://forum.djangoproject.com/t/populating-formset-with-a-query/34017>\
**Category:** Forms & APIs\
**Created:** [August 19, 2024, 9:51pm UTC](https://forum.djangoproject.com/t/populating-formset-with-a-query/34017 "2024-08-19T21:51:23Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![iXanadu](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/ixanadu/32/23350_2.png) [@iXanadu](https://forum.djangoproject.com/u/iXanadu)\
**Post date:** [August 19, 2024, 9:51pm UTC](https://forum.djangoproject.com/t/populating-formset-with-a-query/34017/1 "2024-08-19T21:51:23Z")

</div>

Long time programmer, newer to Django with only a couple lightweight crud and api projects complete. I’m building a survey builder application, and chat-gpt has me knee deep in formsets. Questions are added with a modal that is initiated with a JS call (button pressed). When adding a question, forms are populated by JS, and retrieving the formeset in the view works beautifully. On edit, I need to retrieve the question model and its options (multiple choice) and render the form (and formset). Everything works except I get an empty formset. I don’t know how much code helpers want to see, so I’ll paste in models, forms, form template and the view that’s causing errors. Any pointers in the right direction appreciated.

```class
    survey_section_component = models.ForeignKey(SurveySectionComponent, on_delete=models.CASCADE,
                                                 related_name='surveyquestion_set')
    question_text = models.TextField()
    question_type = models.CharField(max_length=20, choices=[
        ('multiple_choice', 'Multiple Choice'),
        ('short_answer', 'Short Answer'),
        ('paragraph', 'Paragraph'),
        ('dropdown', 'Drop Down'),
        ('checkbox', 'Checkbox'),
        ('rating_scale', 'Rating Scale'),
    ])
    order = models.IntegerField()

    def __str__ (self):
        return self.question_text

    # This method can be used to retrieve the options related to this question
    def get_options(self):
        return self.options.all()

class SurveyQuestionOption(models.Model):
    survey_question = models.ForeignKey(SurveyQuestion, on_delete=models.CASCADE, related_name='options')
    option_text = models.CharField(max_length=255)
    order = models.IntegerField() # Useful if you want to allow ordering of options

    def __str__ (self):
        return self.option_text

class SurveyQuestionForm(forms.ModelForm):
    class Meta:
        model = SurveyQuestion
        fields = ['question_text', 'question_type']

    def __init__ (self, *args, **kwargs):
        super(SurveyQuestionForm, self). __init__ (*args, **kwargs)
        self.fields['question_text'].widget.attrs.update({'class': 'form-control'})
        self.fields['question_type'].widget.attrs.update({'class': 'form-control'})

class SurveyQuestionOptionForm(forms.ModelForm):
    class Meta:
        model = SurveyQuestionOption
        fields = ['option_text', 'order']

    def __init__ (self, *args, **kwargs):
        super(SurveyQuestionOptionForm, self). __init__ (*args, **kwargs)
        self.fields['option_text'].widget.attrs.update({'class': 'form-control'})
        self.fields['order'].widget.attrs.update({'class': 'form-control', 'type': 'number'})

SurveyQuestionOptionFormSet = inlineformset_factory(
    SurveyQuestion,
    SurveyQuestionOption,
    form=SurveyQuestionOptionForm,
    extra=0 # No extra forms initially
)

def edit_question_component(request, component_id):
    component = get_object_or_404(SurveySectionComponent, id=component_id)
    question = get_object_or_404(SurveyQuestion, survey_section_component=component)

    if request.method == 'POST':
        question_form = SurveyQuestionForm(request.POST, instance=question)
        option_formset = SurveyQuestionOptionFormSet(request.POST, instance=question)
        if question_form.is_valid() and option_formset.is_valid():
            question_form.save()
            option_formset.save()

            return JsonResponse({'success': True, 'component_id': component.id, 'content': question.question_text})
        else:
            return JsonResponse({'success': False, 'errors': question_form.errors})

# Get request, grab the options and build the edit 
    
    question_form = SurveyQuestionForm(instance=question)

    options = question.options.all()
    print(f"Options for question {question.id}:")

    for option in options:
        print(f"Option Text: {option.option_text}, Order: {option.order}")

    option_formset = SurveyQuestionOptionFormSet(queryset=question.options.all())
    print(f"Option FormSet forms: {[form.cleaned_data for form in option_formset]}")
    for form in option_formset:
        print(form.initial) # This should show the initial data being loaded into the formset
    print(f"Option FormSet {option_formset}")

    form_html = render_to_string('surveys/partials/question_component_form.html', {
        'question_form': question_form,
        'option_formset': option_formset,
        'component_id': component_id,
        'button_text': 'Save Changes',
    }, request=request)
    return JsonResponse({'success': True, 'form_html': form_html})

```

Output from debugging prints  
Options for question 15:  
Option Text: Red, Order: 1  
Option Text: Blue, Order: 2  
Option FormSet forms:   
Option FormSet

---

<div class="post-metadata">

**Author:** ![philgyford](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/philgyford/32/14295_2.png) [@philgyford](https://forum.djangoproject.com/u/philgyford)\
**Post date:** [August 19, 2024, 9:57pm UTC](https://forum.djangoproject.com/t/populating-formset-with-a-query/34017/2 "2024-08-19T21:57:51Z")

</div>

Hello @iXanadu! It would help if you enclosed your code blocks in three backticks so it formats correctly. You can add the language too for syntax highlighting. e.g.:

````
```python
class SurveyQuestion(models.Model):
    # etc
```

````

---

<div class="post-metadata">

**Author:** ![iXanadu](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/ixanadu/32/23350_2.png) [@iXanadu](https://forum.djangoproject.com/u/iXanadu)\
**Post date:** [August 19, 2024, 9:58pm UTC](https://forum.djangoproject.com/t/populating-formset-with-a-query/34017/3 "2024-08-19T21:58:21Z")

</div>

Great - new here. Edited - thanks for the tip.

---

<div class="post-metadata">

**Author:** ![anefta](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/anefta/32/10649_2.png) [@anefta](https://forum.djangoproject.com/u/anefta)\
**Post date:** [August 19, 2024, 11:30pm UTC](https://forum.djangoproject.com/t/populating-formset-with-a-query/34017/4 "2024-08-19T23:30:03Z")

</div>

> [@iXanadu](#):
>
> `option_formset = SurveyQuestionOptionFormSet(request.POST, instance=question)`

Try to pass the queryset like this to your `SurveyQuestionOptionFormSet`:

`option_formset = SurveyQuestionOptionFormSet(request.POST, instance=question, queryset=question.options.all())`

---

<div class="post-metadata">

**Author:** ![iXanadu](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/ixanadu/32/23350_2.png) [@iXanadu](https://forum.djangoproject.com/u/iXanadu)\
**Post date:** [August 20, 2024, 2:07am UTC](https://forum.djangoproject.com/t/populating-formset-with-a-query/34017/5 "2024-08-20T02:07:44Z")

</div>

Thanks for the help - it didn’t work.

---

<div class="post-metadata">

**Author:** ![anefta](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/anefta/32/10649_2.png) [@anefta](https://forum.djangoproject.com/u/anefta)\
**Post date:** [August 20, 2024, 10:34am UTC](https://forum.djangoproject.com/t/populating-formset-with-a-query/34017/6 "2024-08-20T10:34:27Z")

</div>

What is the output? Any form errors? Any javascript console errors - messages? Also, post your templates code.

---

<div class="post-metadata">

**Author:** ![iXanadu](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/ixanadu/32/23350_2.png) [@iXanadu](https://forum.djangoproject.com/u/iXanadu)\
**Post date:** [August 20, 2024, 12:56pm UTC](https://forum.djangoproject.com/t/populating-formset-with-a-query/34017/7 "2024-08-20T12:56:14Z")

</div>

Same output from print statements as before

Output from print statements (below)

```auto
Options for question 15:
Option Text: Red, Order: 1
Option Text: Blue, Order: 2
Option FormSet forms: []
Option FormSet <ul class="errorlist nonfield"><li>(Hidden field TOTAL_FORMS) This field is required.</li><li>(Hidden field INITIAL_FORMS) This field is required.</li></ul>

  <div><input type="hidden" name="options-TOTAL_FORMS" id="id_options-TOTAL_FORMS"><input type="hidden" name="options-INITIAL_FORMS" id="id_options-INITIAL_FORMS"><input type="hidden" name="options-MIN_NUM_FORMS" id="id_options-MIN_NUM_FORMS"><input type="hidden" name="options-MAX_NUM_FORMS" id="id_options-MAX_NUM_FORMS"></div>

```

Relevant part of view:

```python
question_form = SurveyQuestionForm(instance=question)

    options = question.options.all()
    print(f"Options for question {question.id}:")

    for option in options:
        print(f"Option Text: {option.option_text}, Order: {option.order}")

        option_formset = SurveyQuestionOptionFormSet(request.POST, instance=question, queryset=question.options.all())

    print(f"Option FormSet forms: {[form.cleaned_data for form in option_formset]}")
    for form in option_formset:
        print(form.initial) # This should show the initial data being loaded into the formset
    print(f"Option FormSet {option_formset}")

```

template:

```python
<form id="component-form" method="post">
    {% csrf_token %}
    <input type="hidden" id="section-id-input" name="section_id" value="{{ section_id }}">
    <input type="hidden" id="component-type-input" name="component_type" value="question">

    <!-- Render the main question form -->
    {{ question_form.as_p }}

    <!-- Container for options, initially hidden -->
    <div class="options-section" style="display: {% if option_formset.total_form_count > 0 %}block{% else %}none{% endif %};">
        {{ option_formset.management_form }}
        {% for form in option_formset %}
            <div class="form-row">
                {{ form.option_text.label_tag }} {{ form.option_text }}
                {{ form.order.label_tag }} {{ form.order }}
                {{ form.DELETE.label_tag }} {{ form.DELETE }}
            </div>
        {% endfor %}
    </div>

    <!-- Button to add new options dynamically -->
    <button type="button" id="add-option" class="btn btn-secondary">Add Option</button>

    <input type="hidden" id="component-id-input" name="component_id" value="{{ component_id|default:'' }}">
    <button type="submit" class="btn btn-primary">{{ button_text }}</button>
</form>

```

---

<div class="post-metadata">

**Author:** ![anefta](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/anefta/32/10649_2.png) [@anefta](https://forum.djangoproject.com/u/anefta)\
**Post date:** [August 21, 2024, 1:11am UTC](https://forum.djangoproject.com/t/populating-formset-with-a-query/34017/8 "2024-08-21T01:11:55Z")

</div>

> [@iXanadu](#):
>
> ```auto
> SurveyQuestionOptionFormSet = inlineformset_factory(
> SurveyQuestion,
> SurveyQuestionOption,
> form=SurveyQuestionOptionForm,
> extra=0 # No extra forms initially
> )
> 
> ```

Try this: `SurveyQuestionOptionFormSet = inlineformset_factory( SurveyQuestion, SurveyQuestionOption, form=SurveyQuestionOptionForm, extra=1, can_delete=True, fields=['option_text', 'order'] )`

and add paste the output here of the `edit_question_component`:

```auto
def edit_question_component(request, component_id):
    component = get_object_or_404(SurveySectionComponent, id=component_id)
    question = get_object_or_404(SurveyQuestion, survey_section_component=component)

    if request.method == 'POST':
        question_form = SurveyQuestionForm(request.POST, instance=question)
        option_formset = SurveyQuestionOptionFormSet(request.POST, instance=question)
        if question_form.is_valid() and option_formset.is_valid():
            question_form.save()
            option_formset.save()
            return JsonResponse({'success': True, 'component_id': component.id, 'content': question.question_text})
        else:
            return JsonResponse({'success': False, 'errors': question_form.errors})

    question_form = SurveyQuestionForm(instance=question)
    option_formset = SurveyQuestionOptionFormSet(instance=question)

    print(f"Options for question {question.id}:")
    for option in question.options.all():
        print(f"Option Text: {option.option_text}, Order: {option.order}")

    print(f"Option FormSet forms: {[form.initial for form in option_formset]}")
    
    for form in option_formset:
        print(f"Form initial: {form.initial}")

    print(f"Option FormSet: {option_formset}")
    print(f"Management form: {option_formset.management_form}")

    form_html = render_to_string('surveys/partials/question_component_form.html', {
        'question_form': question_form,
        'option_formset': option_formset,
        'component_id': component_id,
        'button_text': 'Save Changes',
    }, request=request)
    return JsonResponse({'success': True, 'form_html': form_html})

```
