Django 1.9
added the Field.disabled attribute:
The disabled boolean argument, when set to True, disables a form field using the disabled HTML attribute so that it won’t be editable by users. Even if a user tampers with the field’s value submitted to the server, it will be ignored in favor of the value from the form’s initial data.
And so you only need to do:
MyChangeForm(ModelForm):
def __init__(self, *args, **kwargs):
super(MyChangeForm, self).__init__(*args, **kwargs)
self.fields['<field_to_disable>'].disabled = True
And creating the form you need:
MyChangeForm(initial={'<field_to_disable>': "something"})
Before version 1.9
you had to:
class MyChangeForm(ModelForm):
def __init__(self, *args, **kwargs):
super(ItemForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if instance and instance.id:
self.fields['<field_to_disable>'].required = False
self.fields['<field_to_disable>'].widget.attrs['disabled'] = True
def clean_<field_to_disable>(self):
# As shown in the above answer.
instance = getattr(self, 'instance', None)
if instance:
return instance.<field_to_disable>
else:
return self.cleaned_data.get('<field_to_disable>', None)
And creating the form you need:
MyChangeForm(instance=MyChange.objects.get_or_create(<field_to_disable>="something"))
This example was based on this question.