我正在实施简单的“成绩簿”应用程序,其中教师可以更新成绩而不允许更改学生的姓名(至少不在更新等级页面上)。为此,我使用了一种只读技巧,最简单的技巧。问题是在 SUBMIT 之后,视图会重新显示为学生的“空白”值。我想让学生的名字重新出现。
以下是展示此问题的最简单示例。 (这是糟糕的数据库设计,我知道,我只提取了代码的相关部分来展示问题。在实际示例中, student 在自己的表中,但问题仍然存在于那里。)
models.py
class Grade1(models.Model):
student = models.CharField(max_length=50, unique=True)
finalGrade = models.CharField(max_length=3)
class Grade1OForm(ModelForm):
student = forms.CharField(max_length=50, required=False)
def __init__(self, *args, **kwargs):
super(Grade1OForm,self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if instance and instance.id:
self.fields['student'].widget.attrs['readonly'] = True
self.fields['student'].widget.attrs['disabled'] = 'disabled'
def clean_student(self):
instance = getattr(self,'instance',None)
if instance:
return instance.student
else:
return self.cleaned_data.get('student',None)
class Meta:
model=Grade1
views.py
from django.forms.models import modelformset_factory
def modifyAllGrades1(request):
gradeFormSetFactory = modelformset_factory(Grade1, form=Grade1OForm, extra=0)
studentQueryset = Grade1.objects.all()
if request.method=='POST':
myGradeFormSet = gradeFormSetFactory(request.POST, queryset=studentQueryset)
if myGradeFormSet.is_valid():
myGradeFormSet.save()
info = "successfully modified"
else:
myGradeFormSet = gradeFormSetFactory(queryset=studentQueryset)
return render_to_response('grades/modifyAllGrades.html',locals())
模板
<p>{{ info }}</p>
<form method="POST" action="">
<table>
{{ myGradeFormSet.management_form }}
{% for myform in myGradeFormSet.forms %}
{# myform.as_table #}
<tr>
{% for field in myform %}
<td> {{ field }} {{ field.errors }} </td>
{% endfor %}
</tr>
{% endfor %}
</table>
<input type="submit" value="Submit">
</form>
答案 0 :(得分:1)
显示只读字段的方法是问题。
由于学生字段被禁用,表单提交将不会将其作为输入,因此显示验证错误消息的错误表单不会获得初始值。
这就是为什么ReadOnly Widget必须比仅仅禁用html字段更复杂。
尝试使用真实ReadOnlyWidget
,覆盖_has_changed
。
以下是我使用的内容。对于实例化,如果它不同,它将采用original_value和可选的display_value。
class ReadOnlyWidget(forms.Widget):
def __init__(self, original_value, display_value=None):
self.original_value = original_value
if display_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
答案 1 :(得分:0)
我在这里伸展自己,所以有些想法:
%您是否嗅到了流量,以确切了解浏览器和服务器之间发送的内容?
%您是否需要将学生姓名作为隐藏字段发送(如果您不这样做,您的数据库更新可能会假设您希望学生空白)?
%你在Python解析之后看过HTML的来源了吗?