How to set initial values for a ModelForm when instance is also given

后端 未结 3 1395
庸人自扰
庸人自扰 2021-01-02 06:54

It seems like if a ModelForm is given an instance, it ignores any values you provide for initial and instead sets it to the value of the instance -- even if tha

3条回答
  •  一向
    一向 (楼主)
    2021-01-02 07:16

    Figured this out after a little bit of googling.

    You have to set the initial value before calling super.

    So instead of looping through self.fields.keys(), I had to type out the list of fields that I wanted and looped through that instead:

    class RegisterForm(forms.ModelForm):
        ... fields here ...
        initial_fields = ['first_name', 'last_name', ... ]
    
        def __init__(self, *args, **kwargs):
            ... other code ...
            self.person = kwargs.pop('person')
            for key in self.initial_fields:
                if hasattr(self.person, key):
                    self.fields[k].initial = getattr(self.person, key)
            super(RegisterForm, self).__init__(*args, **kwargs)
    

    @Daria rightly points out that you don't have self.fields before calling super. I'm pretty sure this will work:

    class RegisterForm(forms.ModelForm):
        ... fields here ...
        initial_fields = ['first_name', 'last_name', ... ]
    
        def __init__(self, *args, **kwargs):
            ... other code ...
            initial = kwargs.pop('initial', {})
            self.person = kwargs.pop('person')
            for key in self.initial_fields:
                if hasattr(self.person, key):
                    initial[key] = initial.get(key) or getattr(self.person, key)
            kwargs['initial'] = initial
            super(RegisterForm, self).__init__(*args, **kwargs)
    

    In this version, we use the initial argument to pass the values in. It's also written so that if we already have a value in initial for that field, we don't overwrite it.

提交回复
热议问题