trouselife
trouselife

Reputation: 969

Django forms - best practice to set initial values in __init__() method

Sorry if this is a broad question, but I am trying to understand the best practice way to set initial values, edit fields (make readonly for E.g) in a django form init() method.

Take my form for instance:

class ResultForm(forms.ModelForm):

    evidence = forms.CharField(
                widget=forms.Textarea(attrs={'rows': 3, 'cols': 60}),
                label='Evidence:',
                required=False,
            )

    def __init__(self, *args, **kwargs):
        super(ResultForm, self).__init__(*args, **kwargs)

        result_obj = self.instance
        if result_obj.tier_id:

            self.fields['evidence'].widget.attrs['readonly'] = True
            self.fields['evidence'].widget.attrs['class'] = 'classified' 

        else:
              ... do stuff ...

              self.initial['evidence'] = new_evidence_variable   



    class Meta:
        model = Result
        fields = (
                'id',
                'evidence',
                'tier_id',
            )

This is fine to render the unbound form, however when I attempt to validate it with POST data, the init method is run without a proper instance, and it fails.

My way around this, is putting my code in init in a try/except block:

class ResultForm(forms.ModelForm):

    evidence = forms.CharField(
                widget=forms.Textarea(attrs={'rows': 3, 'cols': 60}),
                label='Evidence:',
                required=False,
            )

    def __init__(self, *args, **kwargs):
        super(ResultForm, self).__init__(*args, **kwargs)

        try:
            result_obj = self.instance
            if result_obj.tier_id:

                self.fields['evidence'].widget.attrs['readonly'] = True
                self.fields['evidence'].widget.attrs['class'] = 'classified' 

            else:
                  ... do stuff ...

                  self.initial['evidence'] = new_evidence_variable   

        except:
            pass


    class Meta:
        model = Result
        fields = (
                'id',
                'evidence',
                'tier_id',
            ) 

This seems to work, however it seems a little hacky. Is there a 'better' or more django proposed way to do this?

Upvotes: 1

Views: 2657

Answers (1)

Devang Padhiyar
Devang Padhiyar

Reputation: 3697

Yes, you are right about that. But it need following tweaks to update

If ResultForm class contains instance than do as following if else check

class ResultForm(forms.ModelForm):

    evidence = forms.CharField(
                widget=forms.Textarea(attrs={'rows': 3, 'cols': 60}),
                label='Evidence:',
                required=False,
            )

    def __init__(self, *args, **kwargs):
        super(ResultForm, self).__init__(*args, **kwargs)


        result_obj = self.instance
        if result.obj:   # Checks if result_obj is None or not

           self.fields['evidence'].widget.attrs['readonly'] = True
           self.fields['evidence'].widget.attrs['class'] = 'classified' 

        else:
           ... do stuff ...
           self.initial['evidence'] = new_evidence_variable   


    class Meta:
        model = Result
        fields = (
                'id',
                'evidence',
                'tier_id',
            ) 

Upvotes: 2

Related Questions