Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make optionally read-only fields in django forms?

I have a read-only field in a django form that I sometimes want to edit.
I only want the right user with the right permissions to edit the field. In most cases the field is locked, but an admin could edit this.

Using the init function, I am able to make the field read-only or not, but not optionally read-only. I also tried passing an optional argument to StudentForm.init but that turned much more difficult that I expected.

Is there a proper way to do accomplish this?

models.py

 class Student():
   # is already assigned, but needs to be unique
   # only privelidged user should change.
   student_id = models.CharField(max_length=20, primary_key=True) 
   last_name = models.CharField(max_length=30)
   first_name = models.CharField(max_length=30)
   # ... other fields ...

forms.py

 class StudentForm(forms.ModelForm):
   class Meta:
     model = Student
     fields = ('student_id', 'last_name', 'first_name', 
     # ... other fields ...


   def __init__(self, *args, **kwargs):
       super(StudentForm, self).__init__(*args, **kwargs)
       instance = getattr(self, 'instance', None)
       if instance: 
          self.fields['student_id'].widget.attrs['readonly'] = True

views.py

 def new_student_view(request):
   form = StudentForm()
   # Test for user privelige, and disable 
   form.fields['student_id'].widget.attrs['readonly'] = False
   c = {'form':form}
   return render_to_response('app/edit_student.html', c, context_instance=RequestContext(request))
like image 625
codingJoe Avatar asked Jan 20 '23 21:01

codingJoe


1 Answers

Is that what you are looking for? By modifying your code a little bit:

forms.py

class StudentForm(forms.ModelForm):

    READONLY_FIELDS = ('student_id', 'last_name')

    class Meta:
        model = Student
        fields = ('student_id', 'last_name', 'first_name')

    def __init__(self, readonly_form=False, *args, **kwargs):
        super(StudentForm, self).__init__(*args, **kwargs)
        if readonly_form:
            for field in self.READONLY_FIELDS:
                self.fields[field].widget.attrs['readonly'] = True

views.py

def new_student_view(request):

    if request.user.is_staff:
        form = StudentForm()
    else:
        form = StudentForm(readonly_form=True)

    extra_context = {'form': form}
    return render_to_response('forms_cases/edit_student.html', extra_context, context_instance=RequestContext(request))

So the thing is to check permissions on the views level, and then to pass argument to your form when it is initialized. Now if staff/admin is logged in, fields will be writeable. If not, only fields from class constant will be changed to read only.

like image 144
1234sdf Avatar answered Jan 30 '23 19:01

1234sdf