1

I have a form with several fields that I would like to show to the user but prevent them from editing (should not be an edit box).

My form class looks like this and I'm using the fields meta to have them automatically defined. I'm looking to prevent user from changing their username and email after registration.

class UserEditForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password')

The question In a Django form, how do I make a field readonly (or disabled) so that it cannot be edited? doesn't provide an answer to what to do if the fields are defined automatically using meta.

I've tried

disabled = ('username', 'email',)

And a few other options but nothing seems to work. I'm looking to prevent someone from also changing the form and submitting it (and the data getting changed) as the previous question suggested can be done.

[Edit]: Using Django 1.11

odyssy3105
  • 97
  • 1
  • 8

3 Answers3

4

You can set the disabled property on the fields you need to after the form as been initialised:

class UserEditForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password')

    def __init__(self, *args, **kwargs):
        super(UserEditForm, self).__init__(*args, **kwargs)
        self.fields['username'].disabled = True
        self.fields['email'].disabled = True
Gavin Clark
  • 299
  • 2
  • 3
  • Yeah, this was what I thought too. The `disabled` variable is a `Field` boolean argument, not a list definition like `fields`. – OptimusCrime Oct 11 '17 at 11:45
  • Exactly what I was looking for. Thank you, very helpful. Fields are in an Edit but are disabled. Haven't tested whether hacking them would be prevented, but from the Django docs it looks like they would be ignored. – odyssy3105 Oct 11 '17 at 12:50
1

Since disabled form elements are ignored in Django form validation, disabling mandatory fields will result in a validation error. Therefore a JQuery fix can do this:

$(document).ready(function() {
   ... CHECK IF FORM IS IN EDIT STATE ...

        // disable form controls
        $('select#id_caseType').prop("disabled", true );

Then at Submit method, right before submitting the form, just enable those fields only (so the values will be included in form):

    $('#demo-form2').on('submit',function(){
        // enable the previously disabled form fields in edit mode
        $('select#id_caseType').prop("disabled", false );

Of course this can be done in a generic way by, adding all disabled fields into an array or assigning class that makes JQuery selection easier (ie. all such fields can be added a 'disabled' class)

0

Although Gavin already answered I'm leaving this if somebody else has the same problem.

I think this is exactly what you were asking:

In admin.py, next to list_display, add this line:

readonly_fields = ('username', 'email',)
Sergi7
  • 21
  • 1
  • 5