Django inline formset not saving default values

I have a child inlineformset that saves if it has been changed by the user, but does not save the default value if left unchanged.

SeVsEff is the child, and patient is the parent

models.py

class Patient(TimeStampedModel):
    patient_id = models.UUIDField(
        primary_key=True, unique=True, default=uuid.uuid4, editable=False
    )
    name = models.CharField("Patient Name", max_length=255)

    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL
    )

class SeVsEff(TimeStampedModel):
    value = models.IntegerField(default=20)
    patient = models.ForeignKey(Patient, on_delete=models.CASCADE)

forms.py

class PatientForm(ModelForm):
    class Meta:
        model = Patient
        fields = ["name"]

SevseffFormSet = inlineformset_factory(
    Patient,
    SeVsEff,
    fields=("value",),
    widgets={'value': RangeInput()},
    extra=0,
    min_num=1,
    validate_min=True,
    labels=None,
)

views.py

    def post(self, *args, **kwargs):
        form = PatientForm(data=self.request.POST)
        sevseff_formset = SevseffFormSet(data=self.request.POST)

        if form.is_valid():
            patient_instance = form.save()
            patient_instance.user = self.request.user
            patient_instance.save()

            if sevseff_formset.is_valid():
                sevseff_name = sevseff_formset.save(commit=False)
                for sevseff in sevseff_name:
                    sevseff.patient = patient_instance
                    sevseff.save()

So I think the issues is that the sevseff_formset is not registered as valid unless it is changed, but if I add something like:

            if not sevseff_formset.has_changed():
                sevseff_name = sevseff_formset.save(commit=False)
                for sevseff in sevseff_name:
                    sevseff.patient = patient_instance
                    sevseff.save()

This doesn’t work as sevseff_name is empty.

Correct. This is the expected and documented behavior.

From the docs:

If the extra forms with initial data aren’t changed by the user, they won’t be validated or saved.

If you need to add rows, you’ll need to identify which ones still need to be added.
Or, you could create all the necessary rows before building the formset.

Thanks @KenWhitesell I always wish for a single value for SeVsEff to be saved, and I want this to be the default value if the user doesn’t adjust the form. So is the solution to check if the value exists and if it doesnt add it?

The current approach to this (below) isnt working, is this the right track, or another approach entirely?

        if not sevseff_formset.has_changed():
            sevseff_name = sevseff_formset.save(commit=False)
            for sevseff in sevseff_name:
                sevseff.patient = patient_instance
                sevseff.save()

I’d suggest a slightly different approach.

Note: Haven’t tried this - may take some fiddling to make it work. But I’d try something along the lines of:

sevseff_name = sevseff_formset.save(commit=False)
for sevseff in sevseff_name:
    sevseff.patient = patient_instance
    sevseff.save()
if not sevseff_name:
    SeVsEff(value=20, patient=patient_instance).save()

Thank you!!! Had been trying to fix this for ages and that does it!