How to implement readonly form fields

I submitted my second Ticket to Django: Django ticket #10442:

I saw ticket #3990 , but IMHO, if a ModelForm has an explicit fields list, and if some of these fields are not editable, then they should be rendered as readonly widgets. That’s the least surprising behaviour. Currently they are just ignored. I am trying to write a patch, but I’m new to Django.

I even started with the patch:

  • django/forms/fields.py:

    Field.__init__() has a new keyword argument “readonly”.

  • django/forms/util.py:

    flatatt() now supports None values in the dictionary. These don’t become a key=”value” pair but a simple attribute without value.

  • django/forms/models.py: model_to_dict() now also adds non-ediable fields to the dictionary.

I changed my working copy of Django to do the following:

>>> class ContactForm(forms.Form):
...     id = forms.IntegerField(readonly=True)
...     fname = forms.CharField(max_length=20)
...     lname = forms.CharField(max_length=20)
>>> frm = ContactForm()
>>> s=frm.as_p()

<p><label for="id_id">Id:</label>
<input readonly type="text" name="id" id="id_id" />
<p><label for="id_fname">Fname:</label>
<input id="id_fname" type="text" name="fname" maxlength="20" />
<p><label for="id_lname">Lname:</label>
<input id="id_lname" type="text" name="lname" maxlength="20" />

But then my ticket had been already set to “wontfix”. And now I agree with the Django developers because I got enlightened:

Forms are not meant to contain layout. That’s also why the field order (Django ticket #8164) is not really important in Forms. If you want to define layout without fiddling with templates, then you’ll want a Report.