【问题标题】:How do you upload a file from a form in a Django test through Client.post()?如何通过 Client.post() 从 Django 测试中的表单上传文件?
【发布时间】:2017-03-11 19:54:04
【问题描述】:

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

视图的部分代码:

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,但我无法理解该解决方案以适应我的代码。

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

任何帮助或提示将不胜感激。谢谢!

【问题讨论】:

    标签: python html django forms


    【解决方案1】:

    过去我的做法略有不同,使用的是在测试用例中生成的文件,没有触及文件系统:

        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

    【讨论】:

    • 谢谢,我会检查一下
    • 当我尝试这种方法时,我得到一个表单验证错误:AssertionError ---------------------------- ---------------------------------- 捕获的标准输出调用 ------------- --------------------------------------------------
      • my_file
        • 此字段为必填项。
    • 在测试用例的下一行查看response.context['form'].errors,看看可能是什么原因。
    • @nimasmi 不应该是ContentFile(b"Some file content")吗?
    • @yofee,哦,是的。这到底是怎么发生的?我猜,大脑没有参与。已更正。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    • 2018-01-22
    • 1970-01-01
    • 2020-08-30
    • 1970-01-01
    相关资源
    最近更新 更多