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:
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
readonlyattribute on the form field:Or, replace
if instance and instance.pkwith another condition indicating you’re editing. You could also set the attributedisabledon the input field, instead ofreadonly.The
clean_skufunction will ensure that thereadonlyvalue won’t be overridden by aPOST.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
ModelFormthat excludes the uneditable field(s), and just print them inside your template.