是否可以在 运行 时间动态更改表单小部件的属性

Is it possible to dynamically change the attribute of a form widget at run time

我目前有一个看起来像这样的对象

class StudentDetails(forms.Form):
    school_name = forms.CharField(required=True, widget=forms.TextInput(attrs={'readonly': 'readonly'}))
    student_name= forms.CharField(required=True)
    student_user_name = forms.CharField(required=True)

现在,这些字段在呈现之前会预先填充到视图中

 return render(request, 'manageStudent.html',
                  {'form': StudentDetails(
                      initial={
                          'school_name': rslt[0][1],
                          'student_name': rslt[0][2],
                          'student_user_name': rslt[0][3]
                      })})

我的问题是是否可以禁用 student_user_name 字段?我想将启用的字段表单切换为禁用?

您可以通过将字段的 disabled 参数设置为 True 来禁用它。

这里有更多信息:https://docs.djangoproject.com/en/1.9/ref/forms/fields/#disabled

或者要在浏览网页时更改它,您可以添加一个复选框来控制小部件的行为,如下所示:

在模板中,您将拥有 student_user_nameinput,因此您需要做的就是在表单中添加复选框按钮

<!-- Input of the 'student_user_name' will be already there if you use {{ form }}-->
<!-- <input type="text" name="student_user_name" />-->
<input type="checkbox" id="checkbox"/>

并且在 JavaScript 文件中

$(document).ready(function() {
    $("#checkbox").change(function(){
        if (this.checked){
            $("input[name=student_user_name]").attr("disabled", true);
        } else {
            $("input[name=student_user_name]").attr("disabled", false);
        }
    });
});

首先,一般来说,在表单中使用禁用/只读字段不是一个好主意,尤其是当您真的不希望用户弄乱这些字段的值时。

最安全的选择是有条件地删除表单 init 中的表单字段,如果您愿意,可以将数据从视图本身传递到模板中进行打印。

如果您仍然想继续,请确保在您看来 POST 处理过程中完全不依赖此表单字段。使用您在视图中已经知道的字段值应该是什么。

另外请记住,禁用和只读表单字段之间存在重要区别。 Readonly 会将值传递给您的 POST 数据,而 disabled 则不会。为什么这有关系 ? (因为正如我们所说,无论如何您都不会使用该值)。

确实如此,原因有二:

(1) 如果由于某种原因表单验证失败,您打算在禁用字段中显示的任何内容都将消失,因为 POST 中的 return 不会捕获该字段值。

(2) 如果表单字段是 "required" 就像您的情况一样,它会给您该字段的表单验证错误,因为该值不会保留在 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>