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

Django 是否可以在运行时动态更改表单小部件的属性,django,forms,widget,Django,Forms,Widget,我目前有一个对象,看起来像这样 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(requir

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

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\u user\u name
字段?我想将该字段窗体从启用切换到禁用?

您可以通过将该字段的
disabled
参数设置为
True
将其禁用

更多信息请点击此处:

或者,当您在网页上时,您可以添加一个复选框来控制小部件的行为,如下所示:

在模板中,您将有
学生用户名的
输入
,因此您只需在表单中添加复选框按钮

<!-- 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"/>

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

更多信息请点击此处:

或者,当您在网页上时,您可以添加一个复选框来控制小部件的行为,如下所示:

在模板中,您将有
学生用户名的
输入
,因此您只需在表单中添加复选框按钮

<!-- 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"/>

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

最安全的选择是有条件地删除forminit中的表单字段,而不是将数据从视图本身传递到模板中以便打印(如果愿意)

如果您确实希望继续,请确保在您的视图“后期处理”中根本不依赖此表单字段。使用视图中已知的字段值

还要记住,禁用和只读表单字段之间有一个重要的区别。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
请记住,即使我们将学生\用户名存储在隐藏表单字段中,隐藏表单字段也可能被篡改。因此,不要将视图中的隐藏值用于任何实际存储,而仅用于重新填充失败的提交表单,显示禁用的表单字段值,仅用于示意目的

因此,这就是如何确保在表单提交失败时,即使禁用的表单字段值将消失(这就是为什么我们将其保存在隐藏的表单字段中),您为学生用户名发送的初始值仍将显示:

在显示表单的模板页面中,输入以下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>

$(文档).ready(函数(){
if($('input[name=hidden\u student\u user\u name')).val(){
var hidden_student_user_name=$('input[name=hidden_student_user_name]')。val()
$('input[name=student\u user\u name]')。prop('disabled',false)
$('input[name=student\u user\u name]').val(隐藏的\u student\u user\u name)
$('input[name=student\u user\u name]')。prop('disabled',true)
}
});

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

最安全的选择是有条件地删除forminit中的表单字段,而不是将数据从视图本身传递到模板中以便打印(如果愿意)

如果您确实希望继续,请确保在您的视图“后期处理”中根本不依赖此表单字段。使用视图中已知的字段值

还要记住,禁用和只读表单字段之间有一个重要的区别。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
请记住,即使我们将学生\用户名存储在隐藏表单字段中,隐藏表单字段也可能被篡改。因此,不要将视图中的隐藏值用于任何实际存储,而仅用于重新填充失败的提交表单,显示禁用的表单字段值,仅用于示意目的

因此,这就是如何确保在表单提交失败时,即使禁用的表单字段值将消失(这就是为什么我们将其保存在隐藏的表单字段中),您为学生用户名发送的初始值仍将显示:

在显示表单的模板页面中,输入以下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>

$(文档).ready(函数(){
if($('input[name=hidden\u student\u user\u name')).val(){
var hidden_student_user_name=$('input[name=hidden_student_user_name]')。val()
$('input[name=student\u user\u name]')。prop('disabled',false