首先,一般来说,在表单中使用禁用/只读字段不是一个好主意,特别是如果您真的不希望用户弄乱这些字段的值。
最安全的选择是有条件地删除表单 init 中的表单字段,而是将数据从视图本身传递到模板中以便打印。
如果您还想继续,请确保在您的视图 POST 处理中根本不依赖此表单字段。使用您在视图中已经知道的字段值应该是什么。
另外请记住,禁用和只读表单字段之间存在重要区别。 Readonly 会将值传递给您的 POST 数据,而 disabled 则不会。为什么这有关系 ? (因为您无论如何都不会使用该值,正如我们所谈到的)。
确实如此,原因有二:
(1) 如果表单验证由于某种原因失败,您打算在禁用字段中显示的任何内容都将消失,因为 POST 的返回不会捕获该字段值。
(2) 如果表单字段像您的情况一样是“必需的”,它会给您该字段的表单验证错误,因为该值不会保留在 POST 数据中。
为避免这种情况,您可以尝试在隐藏的表单字段中捕获值并使用 javascript/jquery 将值放入字段中。下面是一个例子:
def __init__(self, *args, **kwargs):
super(StudentDetails, self).__init__(*args, **kwargs)
if 'initial' in kwargs:
_student_user_name = str(kwargs.get('initial').get('student_user_name', None))
if _student_user_name:
self.fields['student_user_name'].widget.attrs['disabled'] = True
self.fields['student_user_name'].required = False
self.fields['hidden_student_user_name'] = forms.CharField(widget=forms.HiddenInput())
self.fields['hidden_student_user_name'].initial = _student_user_name
请记住,即使我们将 student_user_name 存储在隐藏表单字段中,隐藏表单字段也可能被篡改。因此,请勿将视图中的隐藏值用于任何实际存储,而仅用于重新填充已禁用表单字段值的失败提交表单显示,仅用于装饰目的。
因此,即使禁用的表单字段值将消失(这就是我们将其保存在该隐藏表单字段中的原因),您可以确保在表单提交失败期间仍会显示您为学生用户名发送的初始值:
在显示表单的模板页面中,将这段 javascript 代码放入:
<script type="text/javascript">
$(document).ready(function() {
if ( $('input[name=hidden_student_user_name]').val() ) {
var hidden_student_user_name = $('input[name=hidden_student_user_name]').val()
$('input[name=student_user_name]').prop('disabled', false)
$('input[name=student_user_name]').val(hidden_student_user_name)
$('input[name=student_user_name]').prop('disabled', true)
}
});
</script>