Manditory read-only fields in django
- by jamida
I'm writing a test "grade book" application. The models.py file is shown below.
class Student(models.Model):
name = models.CharField(max_length=50)
parent = models.CharField(max_length=50)
def __unicode__(self):
return self.name
class Grade(models.Model):
studentId = models.ForeignKey(Student)
finalGrade = models.CharField(max_length=3)
I'd like to be able to change the final grade for several students in a modelformset but for now I'm just trying one student at a time. I'm also trying to create a form for it that shows the student name as a field that can not be changed, the only thing that can be changed here is the finalGrade. So I used this trick to make the studentId read-only.
class GradeROForm(ModelForm):
studentId = forms.ModelChoiceField(queryset=Student.objects.all())
def __init__(self, *args, **kwargs):
super(GradeROForm,self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if instance and instance.id:
self.fields['studentId'].widget.attrs['disabled']='disabled'
def clean_studentId(self):
instance = getattr(self,'instance',None)
if instance:
return instance.studentId
else:
return self.cleaned_data.get('studentId',None)
class Meta:
model=Grade
And here is my view:
def modifyGrade(request,student):
student = Student.objects.get(name=student)
mygrade = Grade.objects.get(studentId=student)
if request.method == "POST":
myform = GradeROForm(data=request.POST, instance=mygrade)
if myform.is_valid():
grade = myform.save()
info = "successfully updated %s" % grade.studentId
else:
myform=GradeROForm(instance=mygrade)
return render_to_response('grades/modifyGrade.html',locals())
This displays the form like I expect, but when I hit "submit" I get a form validation error for the student field telling me this field is required. I'm guessing that, since the field is "disabled", the value is not being reported in the POST and for reasons unknown to me the instance isn't being used in its place.
I'm a new Django/Python programmer, but quite experienced in other languages. I can't believe I've stumbled upon such a difficult to solve problem in my first significant django app. I figure I must be missing something. Any ideas?