In a Django form, how do I make a field readonly (or disabled) so that it cannot be edited?

django modelform disable field
django disabled field not in post
django admin readonly field
read only fields django serializer
django form fields
django form initial value
django multiple choice field / checkbox
django form widgets example

In a Django form, how do I make a field read-only (or disabled)?

When the form is being used to create a new entry, all fields should be enabled - but when the record is in update mode some fields need to be read-only.

For example, when creating a new Item model, all fields must be editable, but while updating the record, is there a way to disable the sku field so that it is visible, but cannot be edited?

class Item(models.Model):
    sku = models.CharField(max_length=50)
    description = models.CharField(max_length=200)
    added_by = models.ForeignKey(User)


class ItemForm(ModelForm):
    class Meta:
        model = Item
        exclude = ('added_by')

def new_item_view(request):
    if request.method == 'POST':
        form = ItemForm(request.POST)
        # Validate and save
    else:
            form = ItemForm()
    # Render the view

Can class ItemForm be reused? What changes would be required in the ItemForm or Item model class? Would I need to write another class, "ItemUpdateForm", for updating the item?

def update_item_view(request):
    if request.method == 'POST':
        form = ItemUpdateForm(request.POST)
        # Validate and save
    else:
        form = ItemUpdateForm()

As pointed out in this answer, 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.

With Django 1.8 and earlier, to disable entry on the widget and prevent malicious POST hacks you must scrub the input in addition to setting the readonly attribute on the form field:

class ItemForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(ItemForm, self).__init__(*args, **kwargs)
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            self.fields['sku'].widget.attrs['readonly'] = True

    def clean_sku(self):
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            return instance.sku
        else:
            return self.cleaned_data['sku']

Or, replace if instance and instance.pk with another condition indicating you're editing. You could also set the attribute disabled on the input field, instead of readonly.

The clean_sku function will ensure that the readonly value won't be overridden by a POST.

Otherwise, there is no built-in Django form field which will render a value while rejecting bound input data. If this is what you desire, you should instead create a separate ModelForm that excludes the uneditable field(s), and just print them inside your template.

In a Django form, how do I make a field readonly (or disabled) so that, Create a disabled or read only field in django model form. Users screw up forms in all ways possible so there can be Small edit to html will let user change data and send via form submission to over ride existing value. As pointed out in this answer, 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.


Django 1.9 added the Field.disabled attribute: https://docs.djangoproject.com/en/stable/ref/forms/fields/#disabled

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.

Disabled / Read-only field in django ModelForm, In a Django form, how do I make a field read-only (or disabled)? the record, is there a way to disable the sku field so that it is visible, but cannot be edited? In a Django form, how do I make a field readonly(or disabled) so that it cannot be edited? (18) In a Django form, how do I make a field read-only (or disabled)? When the form is being used to create a new entry, all fields should be enabled - but when the record is in update mode some fields need to be read-only.


Setting READONLY on widget only makes the input in the browser read-only. Adding a clean_sku which returns instance.sku ensures the field value will not change on form level.

def clean_sku(self):
    if self.instance: 
        return self.instance.sku
    else: 
        return self.fields['sku']

This way you can use model's (unmodified save) and aviod getting the field required error.

In a Django form, how do I make a field readonly (or disabled) so , But it should be an option for show a field without can to editing it. These are truly non-editable fields, not just temporarily disabled. Intercepting the form, finding the field that you want to make read-only and then modifying its widget is a So my idea would be to implement it as a widget + an option in model definition. Note that the readonly attribute does not keep Django from processing any value sent by the client. If it is important to you that the value doesn't change, no matter how creative your users are with FireBug , you need to use a more involved method, e.g. a ReadOnlyField / ReadOnlyWidget like demonstrated in a blog entry by Alex Gaynor.


awalker's answer helped me a lot!

I've changed his example to work with Django 1.3, using get_readonly_fields.

Usually you should declare something like this in app/admin.py:

class ItemAdmin(admin.ModelAdmin):
    ...
    readonly_fields = ('url',)

I've adapted in this way:

# In the admin.py file
class ItemAdmin(admin.ModelAdmin):
    ...
    def get_readonly_fields(self, request, obj=None):
        if obj:
            return ['url']
        else:
            return []

And it works fine. Now if you add an Item, the url field is read-write, but on change it becomes read-only.

Form fields | Django documentation, remove the effects of the attribute. Instead use removeAttribute('readonly') . The reason you don't want to do this is because someone can change your disabled field to enabled and then submit the form. You would have to change the save function as to not insert the "disabled" data. The standard way to do this is to not put the name in an input, but to display it as text This is not possible in django.


To make this work for a ForeignKey field, a few changes need to be made. Firstly, the SELECT HTML tag does not have the readonly attribute. We need to use disabled="disabled" instead. However, then the browser doesn't send any form data back for that field. So we need to set that field to not be required so that the field validates correctly. We then need to reset the value back to what it used to be so it's not set to blank.

So for foreign keys you will need to do something like:

class ItemForm(ModelForm):

    def __init__(self, *args, **kwargs):
        super(ItemForm, self).__init__(*args, **kwargs)
        instance = getattr(self, 'instance', None)
        if instance and instance.id:
            self.fields['sku'].required = False
            self.fields['sku'].widget.attrs['disabled'] = 'disabled'

    def clean_sku(self):
        # As shown in the above answer.
        instance = getattr(self, 'instance', None)
        if instance:
            return instance.sku
        else:
            return self.cleaned_data.get('sku', None)

This way the browser won't let the user change the field, and will always POST as it it was left blank. We then override the clean method to set the field's value to be what was originally in the instance.

#342 (Add a way for fields to be displayed in the admin without , stores data like the total number of forms, the initial number of forms and the maximum number of forms in a management form. The cleanest way is to create a new base form class that has a readonlyfields meta option, and does the rest of the work for you.. You shouldn't have any of that logic in the template, but rather validate data in the view, and put let django render readonly input as a span widget.


HTML5 Forms: Readonly Type Attribute, gives you an automatically-generated database-access API; see Making queries. Dynamically setting readonly_fields in django admin. In a Django form, how do I make a field readonly (or disabled) so that it cannot be edited? 665.


Adding forms dynamically to a Django formset, You can't use this decorator if you have to reference your model admin class in its __init__() Such modules are expected to register models with the admin. Use the fields option to make simple layout changes in the forms on the “add” and values defined in ModelAdmin.readonly_fields to be displayed as read-​only. If you want to keep the field non-editable throughout then @Till Backhaus' answer is the better option. Original Answer. One way to do this would be to use a custom ModelForm in admin. This form can override the required field to make it editable. Thereby you retain editable=False everywhere else but Admin. For e.g. (tested with Django 1.2.3)


Models | Django documentation, In a Django form, how do I make a field readonly (or disabled) so that it cannot be edited? # https://stackoverflow.com/a/15134622/4126114. #. # Usage of either  Now django-crispy-forms will add to crispy-forms templates context, a variable named form_read_only.Let's see how to use it. Now you would have to go and edit the field.html template and change it so that it looks like this: