为什么Django中的只读表单字段是个坏主意?

时间:2010-05-25 04:32:42

标签: django django-models django-forms

我一直在寻找一种创建只读表单字段的方法,我在这个主题上发现的每篇文章都附带一个声明“这是一个坏主意”。现在对于单个表单,我可以理解还有其他方法可以解决问题,但在modelformset中使用只读表单字段似乎是一个完全自然的想法。

考虑一个教师成绩簿应用程序,老师希望能够通过一个SUBMIT输入所有学生(注意复数学生)成绩。 modelformset可以迭代所有学生成绩,学生姓名是只读的,成绩是可编辑的字段。我喜欢使用modelformset获得的错误检查和错误报告的强大功能和便利性,但是让学生名称在这样的表单中可编辑是疯狂的。

由于专家django的共识是只读表单字段是一个坏主意,我想知道上面的示例学生级示例的标准django最佳实践是什么?

4 个答案:

答案 0 :(得分:24)

您不想这样做的原因是,有人可以将您的禁用字段更改为已启用,然后提交表单。您必须更改保存功能,以便不插入“已禁用”数据。

执行此操作的标准方法是不将名称放在输入中,而是将其显示为文本

<form>
    <div>
        <label>Name</label>
        <p>Johnny Five</p>
    </div>
    <div>
        ....

这在django中是不可能的。

我说如果你真的相信你的用户群不会“搞乱”事情那么就去做吧,但是如果它是一个面向公众的网站,可能会有敏感数据,那就远离它。

答案 1 :(得分:10)

就我的情况而言,这是理想的答案:

https://stackoverflow.com/a/2242468/1004781

即,只需在模板中打印模型变量:

{{ form.instance.LastName }}

答案 2 :(得分:1)

使用禁用字段时,如果表单验证失败,还需要确保它仍然正确填充。这是我的方法,它还负责恶意尝试更改提交的数据:

class MyForm(forms.Form):

    MY_VALUE = 'SOMETHING'
    myfield = forms.CharField(
        initial=MY_VALUE,
        widget=forms.TextInput(attrs={'disabled': 'disabled'})

    def __init__(self, *args, **kwargs):

        # If the form has been submitted, populate the disabled field
        if 'data' in kwargs:
            data = kwargs['data'].copy()
            self.prefix = kwargs.get('prefix')
            data[self.add_prefix('myfield')] = MY_VALUE
            kwargs['data'] = data

        super(MyForm, self).__init__(*args, **kwargs) 

答案 3 :(得分:0)

对于学生/评分示例,我提出了一个解决方案,其中学生是不可编辑的字段,并且可以根据需要编辑和更新成绩。 something like this

我正在使用zip函数在view.py中的grade_edit类中将学生对象和formset结合起来。

MSF4JSpringApplication
            .run(DummyClass.class, args);

我的模板看起来像这样

def grade_edit(request, id):
    student = student.objects.get(id=id)
    grades = grades.objects.filter(studentId=id)
    gradeformset = GradeFormSet(request.POST or None)
    if request.POST:
        gradeformset = GradeFormSet(request.POST, request.FILES, instance=student)
        if gradeformset.is_valid():
            gradeformset.save()
            grades = grades.objects.filter(studentId=id)
            return render(request, 'grade_details.html', {'student': student, 'grades': grades})
    else:
        gradeformset = GradeFormSet(instance=student)
        grades = grades.objects.filter(studentId=id)
        zips = zip(grades, gradeformset)
    return render(request, 'grade_edit.html', {'zips': zips, 'student': student, 'gradeformset': gradeformset })

您可以在此处阅读有关Django formset的更多信息 http://whoisnicoleharris.com/2015/01/06/implementing-django-formsets.html