Search code examples
pythondjangodjango-formsinline-formset

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.


Solution

  • This does it:

    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()
    

    Solution from https://forum.djangoproject.com/t/django-inline-formset-not-saving-default-values/10647/3