You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测试Django中ExportActionMixin生成的导出文件?

问题描述

我想测试Django后台中由import_export.admin.ExportActionMixin生成的导出文件,查看下载的文件内容,但测试时遇到问题:返回状态码是200,但Content-Type是text/html; charset=utf-8而非预期的text/csv,无法获取导出的文件内容。

我的Admin模型

@admin.register(MyModel)
class MyModelAdmin(ExportActionMixin, admin.ModelAdmin):
    resource_class = MyResource

我的资源类

class MyResource(resources.ModelResource):
    class Meta:
        model = MyModel
        headers = ('User ID', 'name')
        fields = ('user__id', 'user__name')

    def get_export_order(self):
        return self.Meta.fields

    def get_export_headers(self):
        return self.Meta.headers

    def get_queryset(self):
        # 注意:此处super调用参数错误,需修正为MyResource
        queryset = super(MyResource, self).get_queryset()
        return queryset.select_related('user')

原测试代码

class MyTestCase(TestCase):
    def setUp(self):
        self.client = Client()
        user = User.objects.create(login="admin", 
                                   email="admin@example.com", 
                                   password="password")
        user.is_staff = True
        user.is_superuser = True
        user.save()
        self.client.login(username="admin", password="password")
    
    def test_import(self):
        url = reverse('/admin/project/mymodel')

        data = {'action': 'export_admin_action',
                'file_format': 0,
                '_selected_action': 1}

        response = self.client.post(url, data=data, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/csv', response['Content-Type'])
        self.assertTrue(response.has_header('Content-Disposition'))
问题分析与解决方案

错误原因

  1. Reverse用法错误:reverse()需传入Django Admin的URL名称(格式为admin:<app_label>_<model_name>_changelist),而非直接路径字符串。
  2. 测试数据缺失:_selected_action指定的ID=1不存在,需提前创建对应MyModel实例。
  3. Follow=True干扰响应:导出动作直接返回文件响应,follow=True会让客户端跟随重定向,最终拿到HTML页面而非文件。
  4. 资源类super调用错误:原代码中super(MyModel, self)参数错误,会触发类型异常。

修正后的测试代码

import csv
from django.contrib.auth.models import User
from django.test import TestCase, Client
from django.urls import reverse
from myapp.models import MyModel  # 替换为你的实际模型路径

class MyTestCase(TestCase):
    def setUp(self):
        self.client = Client()
        # 创建管理员用户
        self.admin_user = User.objects.create_user(
            username="admin", 
            email="admin@example.com", 
            password="password"
        )
        self.admin_user.is_staff = True
        self.admin_user.is_superuser = True
        self.admin_user.save()
        self.client.login(username="admin", password="password")
        
        # 创建测试用实例
        self.test_user = User.objects.create(username="testuser", id=100)
        self.test_model = MyModel.objects.create(user=self.test_user)

    def test_export_action(self):
        # 使用正确的Admin列表页URL
        url = reverse('admin:project_mymodel_changelist')  # 替换为你的app_label和model_name

        # POST数据:_selected_action需为列表格式(支持多选)
        data = {
            'action': 'export_admin_action',
            'file_format': 0,  # 0对应CSV格式
            '_selected_action': [self.test_model.id],
        }

        # 不使用follow=True,直接获取原始文件响应
        response = self.client.post(url, data=data)

        # 验证响应基本信息
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response['Content-Type'], 'text/csv')
        self.assertTrue('attachment; filename=' in response['Content-Disposition'])

        # 解析并验证CSV内容
        csv_content = response.content.decode('utf-8')
        reader = csv.reader(csv_content.splitlines())
        rows = list(reader)
        
        # 验证表头
        self.assertEqual(rows[0], ['User ID', 'name'])
        # 验证数据行
        self.assertEqual(rows[1], [str(self.test_user.id), self.test_user.username])

关键说明

  • URL名称规则:Admin页面的URL名称固定为admin:<app_label>_<model_name>_changelist,需根据你的项目实际配置替换。
  • _selected_action格式:必须传入列表(支持多选导出),不能直接传单个ID值。
  • CSV内容解析:通过response.content.decode('utf-8')将二进制响应转为字符串,再用csv.reader解析后验证表头和数据。

内容的提问来源于stack exchange,提问作者NSS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 16:14:58