[Fixed]-How can I disable a model field in a django form

49πŸ‘

βœ…

Step 1: Disable the frontend widget

Use the HTML readonly attribute:
http://www.w3schools.com/tags/att_input_readonly.asp

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

You can inject arbitrary HTML key value pairs via the widget attrs property:

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

Step 2: Ensure the field is effectively disabled on backend

Override your clean method for your field so that regardless of POST input (somebody can fake a POST, edit the raw HTML, etc.) you get the field value that already exists.

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

12πŸ‘

From 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
πŸ‘€xleon

8πŸ‘

Have you tried using the exclude function?

something like this

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

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

Reference Here

πŸ‘€darren

4πŸ‘

Just customize the widget instance for the status field:

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

see: Django Documentation

4πŸ‘

There is a very easy way of doing it:

class GenerateCertificate(models.Model):

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

The editable=False will make the field disabled for editing.

πŸ‘€Cool Breeze

Leave a comment