how to initialize input form fields using URL parameters [django]

I can’t set the input field values using the URL The form needs to be filled with data from the URL I tried initial= but it does not work. am I missing something?

from django.shortcuts import render, redirect
from django.http import HttpResponse, request, response
from django.forms import formset_factory
from django.forms import inlineformset_factory
from .models import Participant, CheckingStatus
from .forms import BookForm, ParticipantFormSet

def form_view(request):
    if request.method == 'POST':
        form = BookForm(request.POST)
        formset = ParticipantFormSet(request.POST)
        if form.is_valid() and formset.is_valid():
            book = form.save()
            formset.instance = book
            formset.save()
    else:
        form = BookForm()
        initial_data = request.GET.copy()
        formset = ParticipantFormSet(initial=[request.GET.dict(), request.GET, initial_data] )
    return render(request, 'form.html', {'form': form, 'formset': formset})

We’ll need to see the definition for ParticipantFormSet along with a sample of the URL being submitted.

the url that would be submitted would be localhost:8000/?id_first_name_0=Stumbling

forms.py
# import form class from django
from django import forms
# import GeeksModel from models.py
from .models import Participant, CheckingStatus
from django.forms import ModelForm
from django.forms.models import inlineformset_factory
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Submit, Div

class BookForm(ModelForm):
    class Meta:
        model = CheckingStatus
        fields = "__all__"
        widgets = {
               'checking_status': forms.RadioSelect()
        }
        
        
        
ParticipantFormSet = inlineformset_factory(CheckingStatus, Participant, fields="__all__", extra=5, form=BookForm)

We’ll need to see the Participant model.

There are two things I have noticed so far.

Note that you’ve defined ParticipantFormSet as being an inline formset for the Participant model, but you’re specifying form=BookForm, where BookForm is a model form for CheckingStatus and not Participant.

Also note that an inline formset needs an instance of the parent model in order to build the form. If you don’t have such an instance, then you need to iterate over the formset and apply the parent instance to each instance of the form in the formset before saving it.

Or, I believe you could do something like:

form = BookForm(request.POST)
if form.is_valid():
    book = form.save(commit=False)
    formset = ParticipantFormSet(request.POST, instance=book)
    if formset.is_valid():
        book.save()
        formset.save()
...

Thank you for the notations

Here is the Participant Model

from django.db import models

# Create your models here.
class CheckingStatus(models.Model):
    date = models.DateField()
    time = models.TimeField()
    TYPE_SELECT = (
        ('0', 'Checking In'),
        ('1', 'Checking Out'),
    )
    checking_status = models.CharField(max_length=11,choices=TYPE_SELECT, default= 0)
    

    
class Participant(models.Model):
    checking = models.ForeignKey(CheckingStatus, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)
    age = models.IntegerField()    
    ```

How should i edit my ParticipantFormSet ?

Based upon my previous response, what do you think the changes are that you need to make to your inlineformset_factory and ParticipantFormSet function calls?

You might want to review the docs for Inline formsets, Model formsets and the examples provided.

(Side note: And no, we have not yet gotten to address your original question regarding the use of the URL parameter.)

based on your previous answer I think form=Participant, and I should look over the docs more

Really close - it would be form=ParticipantForm.

The other key point is that you use “instance” to initialize the formset as being a reference to the parent and not “initial”.

So I should fix my model forms first by making a separate form for participant so it can be a initial of it and not a instance?

I kind of slow to understand, apologies

There are a couple of separate and independent issues.

  • The form used in an inline formset is a form for the child model, not the parent. So yes, you need to add a form for Participant to use in that formset.

  • An inline formset is related to one instance of the parent model. You identify which instance the formset is related to by the “instance” parameter. The “initial” parameter has a different usage, which is defined in the docs.

1 Like

I changed my forms.py according to your advice.

Just having a hard time understanding the second bullet point, which I believe is the point you been trying to explain all thread

class CheckingForm(ModelForm):
    class Meta:
        model = CheckingStatus
        fields = "__all__"
        widgets = {
               'checking_status': forms.RadioSelect()
        }
        
class ParticipantForm(ModelForm):
    class Meta:
        model = Participant
        fields = "__all__"
        
ParticipantFormSet = inlineformset_factory(CheckingStatus, Participant, extra=5, form=ParticipantForm)```

Every time I use initial in my formset function call, in views, I get an error.

Also, I can’t seem to find examples of initial in the docs.

How do I use initial instead of instance?