¿Cómo puedo deshabilitar un campo de modelo en un formulario de django?

Tengo un modelo como este:

class MyModel(models.Model): REGULAR = 1 PREMIUM = 2 STATUS_CHOICES = ((REGULAR, "regular"), (PREMIUM, "premium")) name = models.CharField(max_length=30) status = models.IntegerField(choices = STATUS_CHOICES, default = REGULAR) class MyForm(forms.ModelForm): class Meta: model = models.MyModel 

En una vista, inicializo un campo e bash que no sea editable:

 myform = MyForm(initial = {'status': requested_status}) myform.fields['status'].editable = False 

Pero el usuario todavía puede cambiar ese campo.

¿Cuál es la manera real de lograr lo que estoy buscando?

Paso 1: Deshabilita el widget frontend

Utilice el atributo de readonly HTML:
http://www.w3schools.com/tags/att_input_readonly.asp

O atributo disabled :
http://www.w3.org/TR/html401/interact/forms.html#adef-disabled

Puede inyectar pares de valores de clave HTML arbitrarios a través de la propiedad attrs del widget:

 myform.fields['status'].widget.attrs['readonly'] = True # text input myform.fields['status'].widget.attrs['disabled'] = True # radio / checkbox 

Paso 2: Asegúrate de que el campo esté efectivamente deshabilitado en el backend

Anule su método de limpieza para su campo para que, independientemente de la entrada POST (alguien pueda falsificar un POST, editar el HTML sin procesar, etc.) obtenga el valor de campo que ya existe.

 def clean_status(self): # when field is cleaned, we always return the existing model field. return self.instance.status 

¿Has intentado usar la función de exclusión?

algo como esto

 class PartialAuthorForm(ModelForm): class Meta: model = Author fields = ('name', 'title') class PartialAuthorForm(ModelForm): class Meta: model = Author exclude = ('birth_date',) 

Referencia aqui

Solo personaliza la instancia del widget para el campo de estado:

 class MyModel(models.Model): REGULAR = 1 PREMIUM = 2 STATUS_CHOICES = ((REGULAR, "regular"), (PREMIUM, "premium")) name = models.CharField(max_length=30) status = models.IntegerField(choices = STATUS_CHOICES, default = REGULAR) class MyForm(forms.ModelForm): status = forms.CharField(widget=forms.TextInput(attrs={'readonly':'True'})) class Meta: model = models.MyModel 

Ver: Documentación Django.

Desde Django 1.9:

 from django.forms import Textarea class MyModelForm(forms.ModelForm): class Meta: model = MyModel fields = '__all__' widgets = {'my_field_in_my_model': Textarea(attrs={'cols':80,'rows':1}),} def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['my_field_in_my_model'].disabled = True 

Hay una manera muy fácil de hacerlo:

 class GenerateCertificate(models.Model): field_name = models.CharField( max_length=15, editable=False) def __unicode__(self): return unicode(self.field_name) 

El editable=False hará que el campo esté deshabilitado para editar.