Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在Django中使用ModelFormSet测试Post请求_Python_Django_Django Forms_Django Templates - Fatal编程技术网

Python 在Django中使用ModelFormSet测试Post请求

Python 在Django中使用ModelFormSet测试Post请求,python,django,django-forms,django-templates,Python,Django,Django Forms,Django Templates,我是django和测试新手,所以我不确定是否有更简单的解决方案 我正在创建一个评估应用程序,用户可以编辑、提交和更新该应用程序。每个量规都有预设数量的行模型,这些行模型通过外键关系连接到量规模型。用户应该能够更新多行模型中的多行选择字段,并将行选择字段发布到数据库中 为了在模板中描述这一点,我决定使用ModelFormSet并在rubric.html中迭代ModelFormSet。这工作正常,但是每当我尝试使用TestCase测试这个布局时,我都会收到错误消息 ['ManagementForm数

我是django和测试新手,所以我不确定是否有更简单的解决方案

我正在创建一个评估应用程序,用户可以编辑、提交和更新该应用程序。每个量规都有预设数量的行模型,这些行模型通过外键关系连接到量规模型。用户应该能够更新多行模型中的多行选择字段,并将行选择字段发布到数据库中

为了在模板中描述这一点,我决定使用ModelFormSet并在rubric.html中迭代ModelFormSet。这工作正常,但是每当我尝试使用TestCase测试这个布局时,我都会收到错误消息 ['ManagementForm数据丢失或已被篡改']。我理解这个错误,因为测试没有使用rubric.html(ManagementForm所在的位置)将post请求传递给视图,但是应用程序在浏览器中工作,因为django模板将ManagementForm呈现为html,而html在视图中没有问题

您可以使用TestCase在django中测试ModelFormSet,还是必须使用LiveServerTestCase和Selenium?有没有办法让示例测试通过并仍然测试post请求(在使用ModelFormSet时)?非常感谢您的帮助

forms.py

class RowForm(ModelForm):
    class Meta:
        model = Row
        fields = ['row_choice']

class RubricForm(ModelForm):
    class Meta:
        model = Rubric
        fields = ['name']

RowFormSet = modelformset_factory(Row, fields=('row_choice',), extra=0) 
失败测试的一个示例:

def test_rubric_page_can_take_post_request(self):
    self.add_two_classes_to_semester_add_two_students_to_class_add_one_row()
    request = HttpRequest()
    request.method = "POST"
    response = rubric_page(request, "EG5000", "12345678")

    self.assertEqual(response.status_code, 302)
追溯:

Traceback (most recent call last):
  File "C:\python33\assessmenttoolstaging\source\rubricapp\tests\tests.py", line 240, in test_rubric_page_can_take_post_request
    response = rubric_page(request, "EG5000", "12345678")
  File "C:\python33\assessmenttoolstaging\source\rubricapp\views.py", line 52, in rubric_page
    RowFormSetWeb.clean()
  File "C:\Python33\lib\site-packages\django\forms\models.py", line 645, in clean
    self.validate_unique()
  File "C:\Python33\lib\site-packages\django\forms\models.py", line 651, in validate_unique
    forms_to_delete = self.deleted_forms
  File "C:\Python33\lib\site-packages\django\forms\formsets.py", line 205, in deleted_forms
    if not self.is_valid() or not self.can_delete:
  File "C:\Python33\lib\site-packages\django\forms\formsets.py", line 304, in is_valid
    self.errors
  File "C:\Python33\lib\site-packages\django\forms\formsets.py", line 278, in errors
    self.full_clean()
  File "C:\Python33\lib\site-packages\django\forms\formsets.py", line 325, in full_clean
    for i in range(0, self.total_form_count()):
  File "C:\Python33\lib\site-packages\django\forms\formsets.py", line 115, in total_form_count
    return min(self.management_form.cleaned_data[TOTAL_FORM_COUNT], self.absolute_max)
  File "C:\Python33\lib\site-packages\django\forms\formsets.py", line 97, in management_form
    code='missing_management_form',
django.core.exceptions.ValidationError: ['ManagementForm data is missing or has been tampered with']
标题页面视图

def rubric_page(request, edclass, studentname):
    edClassSpaceAdded = re.sub('([A-Z]+)', r'\1 ', edclass)
    enrollmentObj = Enrollment.objects.get(edclass__name=edClassSpaceAdded, student__lnumber=studentname)
    rubricForClass = enrollmentObj.keyrubric.get()
    rows = Row.objects.filter(rubric=rubricForClass)
    student = Student.objects.get(lnumber=studentname)
    if request.method == 'POST':
        #TestCase cannot test this section of the view
        RowFormSetWeb = RowFormSet(request.POST)
        RowFormSetWeb.clean()
        if RowFormSetWeb.is_valid():
            savedFormset = RowFormSetWeb.save(commit=False)
            for i in savedFormset:
                i.rubric = rubricForClass 
            RowFormSetWeb.save()
            return redirect('/'+ edclass + '/')
        else:
            return render(request, 'rubric.html', {'studentlnumber': student.lnumber,'studentname': student.lastname + ", " + student.firstname, 'RowFormSetWeb':RowFormSetWeb, 'rows':rows, 'edclass':edclass})
    else:
        RowFormSetWeb = RowFormSet(queryset=Row.objects.filter(rubric=rubricForClass))
        return render(request, 'rubric.html', {'studentlnumber': student.lnumber,'studentname': student.lastname + ", " + student.firstname, 'RowFormSetWeb':RowFormSetWeb, 'rows':rows, 'edclass':edclass})
rubric.html的表单部分

    <h3 id="rubricheader">TODO Pull model into view</h3>
    <form method="post" action= {% url 'rubricpage' edclass=edclass studentname=studentlnumber %}>

    <table border="1">
<!-- TODO fix this so that it pulls from forms.py -->
        <tr>
            <th></th>
            <th>Excellent</th>
            <th>Proficient</th>
            <th>Sub-par</th>
            <th>Abysmal</th>
        </tr>
            {{ RowFormSetWeb.management_form }}
            {% for form in RowFormSetWeb %}
                {{ form.id }}
            <tr>
                <td>{{ form.row_choice }}</td><td>{{ form.excellenttext }}</td><td>{{ form.proficienttext }}</td><td>{{ form.satisfactorytext }}<td>{{ form.unsatisfactorytext }}</td>
            </tr>
            {{ RowFormSetWeb.errors }}
            {% endfor %}

    </table>
    <input name="submitbutton" type="submit" name="submit" value="Submit" id="rubricsubmit">
{% csrf_token %}
</form>
{% endblock %}
在浏览器中呈现表单的方式:

<form action="/201530/EG5000/21743148/" method="post">
<table border="1">
<!-- TODO fix this so that it pulls from forms.py -->
<tr>
<th></th>
<th>Excellent</th>
<th>Proficient</th>
<th>Sub-par</th>
<th>Abysmal</th>
</tr>
<input id="id_form-TOTAL_FORMS" name="form-TOTAL_FORMS" type="hidden" value="2"/><input id="id_form-INITIAL_FORMS" name="form-INITIAL_FORMS" type="hidden" value="2"/><input id="id_form-MIN_NUM_FORMS" name="form-MIN_NUM_FORMS" type="hidden" value="0"/><input id="id_form-MAX_NUM_FORMS" name="form-MAX_NUM_FORMS" type="hidden" value="1000"/>
<input id="id_form-0-id" name="form-0-id" type="hidden" value="3"/>
<tr>
<td><select id="id_form-0-row_choice" name="form-0-row_choice">
<option value="">Your string for display</option>
<option value="1">Excellent</option>
<option value="2">Proficient</option>
<option value="3">Awful</option>
<option value="4">The worst ever</option>
</select></td>
<td>THE BEST!</td>
<td>THE SECOND BEST!</td>
<td>THE THIRD BEST!</td>
<td>YOURE LAST</td>
</tr>
                                        []

                                                <input id="id_form-1-id" name="form-1-id" type="hidden" value="4"/>
<tr>
<td><select id="id_form-1-row_choice" name="form-1-row_choice">
<option value="">Your string for display</option>
<option value="1">Excellent</option>
<option value="2">Proficient</option>
<option value="3">Awful</option>
<option value="4">The worst ever</option>
</select></td>
<td>THE GREATEST!</td>
<td>THE SECOND BEST!</td>
<td>THE THIRD BEST!</td>
<td>YOURE LAST</td>
</tr>
                                        []



                        </table>
<input id="rubricsubmit" name="submit" type="submit" value="Submit">
<input name="csrfmiddlewaretoken" type="hidden" value="0OeU2n0v8ooXHBxdUfi26xxqMIdrA50L"/>
</input></form>

杰出的
精通的
低于标准
糟糕的
要显示的字符串
杰出的
精通的
可怕的
最糟糕的
最好的!
第二好!
第三好!
你是最后一个
[]
要显示的字符串
杰出的
精通的
可怕的
最糟糕的
最伟大的!
第二好!
第三好!
你是最后一个
[]

我过去使用过的一种方法(虽然不是特别好的方法)是使用客户机获取呈现的表单,然后使用类似BeautifulSoup的方法从中解析出所有表单数据,并在必要时进行更新,然后再发回。这样,您将获得所有隐藏的和预填充的字段,因此您可以确保您的测试与用户的行为相同。

我担心我可能不得不这样做。是否将表单数据作为数据关键字传递到self.client.post(url,data)中?我有点困惑,因为即使我为self.client.post提供了一个包含表单正确数据的字典,我仍然会收到可怕的管理表单错误。谢谢这是我在self.client.post上发布的内容。我将呈现的表单添加到原始帖子中。如果我遗漏了一些非常基本的东西,我道歉
self.client.post(“/201530/EG5000/21743148/”,{“id_form-0-row_-choice”:“1”,“id_form-1-row_-choice”:“2”})
正如错误所说,您也需要来自管理表单的值;ie隐藏字段,如
form-TOTAL\u FORMS
等。谢谢!这样才能通过考试。
<form action="/201530/EG5000/21743148/" method="post">
<table border="1">
<!-- TODO fix this so that it pulls from forms.py -->
<tr>
<th></th>
<th>Excellent</th>
<th>Proficient</th>
<th>Sub-par</th>
<th>Abysmal</th>
</tr>
<input id="id_form-TOTAL_FORMS" name="form-TOTAL_FORMS" type="hidden" value="2"/><input id="id_form-INITIAL_FORMS" name="form-INITIAL_FORMS" type="hidden" value="2"/><input id="id_form-MIN_NUM_FORMS" name="form-MIN_NUM_FORMS" type="hidden" value="0"/><input id="id_form-MAX_NUM_FORMS" name="form-MAX_NUM_FORMS" type="hidden" value="1000"/>
<input id="id_form-0-id" name="form-0-id" type="hidden" value="3"/>
<tr>
<td><select id="id_form-0-row_choice" name="form-0-row_choice">
<option value="">Your string for display</option>
<option value="1">Excellent</option>
<option value="2">Proficient</option>
<option value="3">Awful</option>
<option value="4">The worst ever</option>
</select></td>
<td>THE BEST!</td>
<td>THE SECOND BEST!</td>
<td>THE THIRD BEST!</td>
<td>YOURE LAST</td>
</tr>
                                        []

                                                <input id="id_form-1-id" name="form-1-id" type="hidden" value="4"/>
<tr>
<td><select id="id_form-1-row_choice" name="form-1-row_choice">
<option value="">Your string for display</option>
<option value="1">Excellent</option>
<option value="2">Proficient</option>
<option value="3">Awful</option>
<option value="4">The worst ever</option>
</select></td>
<td>THE GREATEST!</td>
<td>THE SECOND BEST!</td>
<td>THE THIRD BEST!</td>
<td>YOURE LAST</td>
</tr>
                                        []



                        </table>
<input id="rubricsubmit" name="submit" type="submit" value="Submit">
<input name="csrfmiddlewaretoken" type="hidden" value="0OeU2n0v8ooXHBxdUfi26xxqMIdrA50L"/>
</input></form>