Odd behavior in Django Form (readonly field/widget)
Posted
by jamida
on Stack Overflow
See other posts from Stack Overflow
or by jamida
Published on 2010-05-28T19:21:41Z
Indexed on
2010/05/28
19:32 UTC
Read the original article
Hit count: 512
I'm having a problem with a test app I'm writing to verify some Django functionality. The test app is a small "grade book" application that is currently using Alex Gaynor's readonly field functionality http://lazypython.blogspot.com/2008/12/building-read-only-field-in-django.html
There are 2 problems which may be related. First, when I flop the comment on these 2 lines below:
# myform = GradeForm(data=request.POST, instance=mygrade)
myform = GradeROForm(data=request.POST, instance=mygrade)
it works like I expect, except of course that the student field is changeable.
When the comments are the shown way, the "studentId" field is displayed as a number (not the name, problem 1) and when I hit submit I get an error saying that studentId needs to be a Student instance.
I'm at a loss as to how to fix this. I'm not wedded to Alex Gaynor's code. ANY code will work. I'm relatively new to both Python and Django, so the hints I've seen on websites that say "making a read-only field is easy" are still beyond me.
// models.py
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)
# testbed.grades.readonly is alex gaynor's code
from testbed.grades.readonly import ReadOnlyField
class GradeROForm(ModelForm):
studentId = ReadOnlyField()
class Meta:
model=Grade
class GradeForm(ModelForm):
class Meta:
model=Grade
// views.py
def modifyGrade(request,student):
student = Student.objects.get(name=student)
mygrade = Grade.objects.get(studentId=student)
if request.method == "POST":
# myform = GradeForm(data=request.POST, instance=mygrade)
myform = GradeROForm(data=request.POST, instance=mygrade)
if myform.is_valid():
grade = myform.save()
info = "successfully updated %s" % grade.studentId
else:
# myform=GradeForm(instance=mygrade)
myform=GradeROForm(instance=mygrade)
return render_to_response('grades/modifyGrade.html',locals())
// template
<p>{{ info }}</p>
<form method="POST" action="">
<table>
{{ myform.as_table }}
</table>
<input type="submit" value="Submit">
</form>
// Alex Gaynor's code
from django import forms
from django.utils.html import escape
from django.utils.safestring import mark_safe
from django.forms.util import flatatt
class ReadOnlyWidget(forms.Widget):
def render(self, name, value, attrs):
final_attrs = self.build_attrs(attrs, name=name)
if hasattr(self, 'initial'):
value = self.initial
return mark_safe("<span %s>%s</span>" % (flatatt(final_attrs), escape(value) or ''))
def _has_changed(self, initial, data):
return False
class ReadOnlyField(forms.FileField):
widget = ReadOnlyWidget
def __init__(self, widget=None, label=None, initial=None, help_text=None):
forms.Field.__init__(self, label=label, initial=initial,
help_text=help_text, widget=widget)
def clean(self, value, initial):
self.widget.initial = initial
return initial
© Stack Overflow or respective owner