我正在编写用于验证某些 Django 功能的测试应用程序时遇到问题。测试应用程序是一个小型“成绩册”应用程序,目前正在使用 Alex Gaynor 的只读字段功能 http://lazypython.blogspot.com/2008/12/building-read-only-field-in-django.html
有2个问题可能相关。首先,当我对下面这两行的评论失败时:
# myform = GradeForm(data=request.POST, instance=mygrade)
myform = GradeROForm(data=request.POST, instance=mygrade)
它像我期望的那样工作,当然,学生领域是可变的。
当评论以显示方式显示时,“studentId”字段显示为数字(不是名称,问题 1),当我点击提交时,我收到一条错误消息,指出 studentId 需要是 Student 实例。
我不知道如何解决这个问题。我不喜欢 Alex Gaynor 的代码。任何代码都可以。我对 Python 和 Django 都比较陌生,所以我在网站上看到的“制作只读字段很容易”的提示仍然超出我的范围。
//模型.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
// View .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())
//模板
<p>{{ info }}</p>
<form method="POST" action="">
<table>
{{ myform.as_table }}
</table>
<input type="submit" value="Submit">
</form>
//亚历克斯盖诺的代码
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
最佳答案
不要打扰 ReadOnlyField。改用小部件。
这是我经常使用的一种。
class ReadOnlyWidget(forms.Widget):
def __init__(self, original_value, display_value):
self.original_value = original_value
self.display_value = display_value
super(ReadOnlyWidget, self).__init__()
def _has_changed(self, initial, data):
return False
def render(self, name, value, attrs=None):
if self.display_value is not None:
return unicode(self.display_value)
return unicode(self.original_value)
def value_from_datadict(self, data, files, name):
return self.original_value
将它与 CharField 一起使用。
关于django - Django 表单中的奇怪行为(只读字段/小部件),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2931884/