如何通过Client.post()从Django测试中的表单上传文件?

时间:2016-10-28 21:10:54

标签: python html django forms

我正在设计一个Django测试,我在其中上传了一个.xml文件。如果文件正确(由架构验证),则将其数据添加到项目的数据库中。

视图的部分代码:

if request.method == 'POST':
    form = UploadFileForm(request.POST, request.FILES)
    if form.is_valid():
        result = parse_xml_question(request.FILES['docfile'], topic_id)

表格中有以下课程:

class UploadFileForm(forms.Form):
    docfile = forms.FileField(
        label='Select a file',
        help_text='.xml file'
    )

使用表单的html:

<form action="{% url 'add_question_w_subject_topic' subject.id topic.id %}" enctype="multipart/form-data" method="post">
    {% csrf_token %}
    <p>{{ form.non_field_errors }}</p>
    <p>{{ form.docfile.label_tag }}</p>
    <p>
        {{ form.docfile.errors }}
        {{ form.docfile }}
    </p>
    <p><input type="submit" value="Upload" /></p>
</form>

测试失败:

def test_question_file_wrong_format(self):
    c = Client()

    script_dir = os.path.dirname(__file__)
    rel_path = "xml_files/wrong_format.xml"
    abs_file_path = os.path.join(script_dir, rel_path)

    response = c.post('/add/question/'+ str(self.subj1.id) +'/'
        + str(self.topc1.id) + '/', {'docfile': 
        open(abs_file_path, 'rb')})
    self.assertEquals(response.status_code, 200)

注意这一行:

response = c.post('/add/question/'+ str(self.subj1.id) +'/'
            + str(self.topc1.id) + '/', {'docfile': 
            open(abs_file_path, 'rb')})

我尝试了几种方法。在所有这些中,它返回状态代码302,而我期待200

我已阅读this,我无法理解这一点,以便将该解决方案应用于我的代码。

如果您需要更多信息,请告诉我。对不起,如果这是一个已经回答的问题。

非常感谢任何帮助或提示。谢谢!

1 个答案:

答案 0 :(得分:2)

过去,我使用测试用例中生成的文件,而不触及文件系统,这样做略有不同:

    fake_file = ContentFile(b"Some file content")
    fake_file.name = 'myfile.xml'

    post_data = {
        'title': "Test document",
        'file': fake_file,
    }
    url = '/add/question/'+ str(self.subj1.id) +'/' + str(self.topc1.id) + '/'
    response = self.client.post(url, post_data)

如果不这样做,请务必使用content_type='multipart/form-data'提交表单。如果您使用self.client而不是Client,那么如果您包含data参数,则会自动执行此操作。见https://docs.djangoproject.com/en/1.10/topics/testing/tools/#django.test.Client.post