[Solved]-How to set default values in TabularInline formset in Django admin

16👍

from django.utils.functional import curry

class DetailsInline(admin.TabularInline):
    model = Details
    formset = DetailsFormset
    extra = 3

    def get_formset(self, request, obj=None, **kwargs):
        initial = []
        if request.method == "GET":
            initial.append({
                'label': 'first name',
            })
        formset = super(DetailsInline, self).get_formset(request, obj, **kwargs)
        formset.__init__ = curry(formset.__init__, initial=initial)
        return formset

From here: Pre-populate an inline FormSet?

5👍

If what you need is to define default values for the new forms that are created you can redefine the empty_form property of a InlineFormSet:

class MyDefaultFormSet(django.forms.models.BaseInlineFormSet):
    @property
    def empty_form(self):
       form = super(MyDefaultFormSet, self).empty_form
       # you can access self.instance to get the model parent object
       form.fields['label'].initial = 'first name'
       # ...
       return form

 class DetailsInline(admin.TabularInline):
    formset = MyDefaultFormSet

Now, every time you add a new form it contains the initial data you provided it with. I’ve tested this on django 1.5.

2👍

I tried many suggestions from Stackoverflow (Django=4.x), not working for me.
Here is what I did.

class MilestoneFormSet(forms.models.BaseInlineFormSet):
    model = Milestone

    def __init__(self, *args, **kwargs):
        super(MilestoneFormSet, self).__init__(*args, **kwargs)
        if not self.instance.pk: 
            self.initial = [
            {'stage': '1.Plan', 'description': 'Requirements gathering', },
            {'stage': '2.Define', 'description': 'Validate requirement', },
            ]

class MilestoneInline(admin.TabularInline):
    model = Milestone
    formset = MilestoneFormSet  

    def get_extra(self, request, obj=None, **kwargs):
        extra = 0  #default 0
        if not obj: #new create only
            extra = 2 #2 records defined in __init__
        return extra

I hope this works for everyone.

👤AndyC

-2👍

To provide a static default for all instances in the inline, I found a simpler solution that just sets it in a form:

class DetailsForm(django_forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['label'] = 'first_name'


class DetailsInline(admin.TabularInline):
    form = DetailsForm
    # ...

I think this doesn’t work for the OP’s particular case because each form has a different value for the 'label' field, but I hope it can be useful for anyone coming to this page in the future.

Leave a comment