jammon jammon - 1 year ago 112
Python Question

How can I disable a model field in a django form

I have a model like this:

class MyModel(models.Model):
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

In a view I initialize one field and try to make it non-editable:

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

But the user can still change that field.

What's the real way to accomplish what I'm after?

Answer Source

Use the HTML readonly attribute:

Or 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

This post has a nice trick for ensuring your form can't accept new values: In a django form, How to make a field readonly (or disabled) so that it cannot be edited?

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 value you started with.

def clean_status(self):
    return self.instance.status
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download