如何测试Django Admin中带Inline的职位招聘表单?
测试Django Admin内联表单(JobResponseInline)的正确姿势
我来帮你搞定这个测试难题!Django Admin的内联表单对POST数据格式有严格要求,你之前的失败大概率是数据命名规则没踩对,咱一步步来捋清楚:
先搞懂内联表单的POST数据规则
Django Admin处理内联表单时,字段命名和控制字段都有固定格式:
- 内联字段必须以内联实例的前缀开头,默认前缀是小写的模型名(比如你的
JobResponse对应前缀jobresponse);如果给JobResponseInline设置了prefix属性,就得用自定义的前缀。 - 必须包含4个隐藏控制字段:
{prefix}-TOTAL_FORMS、{prefix}-INITIAL_FORMS、{prefix}-MIN_NUM_FORMS、{prefix}-MAX_NUM_FORMS,用来告诉Admin有多少个内联表单需要处理。 - 每个内联实例的字段要按
{prefix}-{索引}-{字段名}的格式命名,索引从0开始,必须连续递增。
举个具体的POST数据示例
假设你的JobResponse模型有applicant_email和message两个必填字段,JobOffer的多语言字段是title_fr,那正确的POST数据应该是这样的:
post_data = { # JobOffer本身的字段 'title_fr': '测试法语职位', # 内联表单的控制字段(前缀用默认的jobresponse) 'jobresponse-TOTAL_FORMS': '2', 'jobresponse-INITIAL_FORMS': '0', 'jobresponse-MIN_NUM_FORMS': '0', 'jobresponse-MAX_NUM_FORMS': '1000', # 第一个内联表单(索引0)的字段 'jobresponse-0-applicant_email': 'test1@example.com', 'jobresponse-0-message': '我想申请这个职位!', # 第二个内联表单(索引1)的字段 'jobresponse-1-applicant_email': 'test2@example.com', 'jobresponse-1-message': '我也对这个职位感兴趣!', }
用Django Test Client写靠谱的测试用例
最稳妥的测试方式是用Django自带的Client模拟Admin请求,步骤如下:
from django.test import TestCase, Client from django.contrib.auth.models import User from your_app.models import JobOffer class JobOfferAdminInlineTest(TestCase): def setUp(self): # 创建有权限的超级用户 self.admin_user = User.objects.create_superuser( username='admin', email='admin@test.com', password='admin123456' ) self.client = Client() # 登录Admin后台 self.client.login(username='admin', password='admin123456') def test_create_job_offer_with_inline_responses(self): # 构造符合规则的POST数据 post_data = { 'title_fr': '测试法语职位', 'jobresponse-TOTAL_FORMS': '2', 'jobresponse-INITIAL_FORMS': '0', 'jobresponse-MIN_NUM_FORMS': '0', 'jobresponse-MAX_NUM_FORMS': '1000', 'jobresponse-0-applicant_email': 'applicant1@test.com', 'jobresponse-0-message': '第一个应聘者的申请消息', 'jobresponse-1-applicant_email': 'applicant2@test.com', 'jobresponse-1-message': '第二个应聘者的申请消息', } # 发送POST请求到JobOffer的添加页面 response = self.client.post('/admin/your_app/joboffer/add/', post_data) # 验证是否重定向到列表页(表示创建成功) self.assertEqual(response.status_code, 302) # 验证数据是否正确保存 job_offer = JobOffer.objects.get(title_fr='测试法语职位') self.assertEqual(job_offer.jobresponse_set.count(), 2) self.assertEqual(job_offer.jobresponse_set.first().applicant_email, 'applicant1@test.com')
常见坑点提醒
- 前缀错误:如果给
JobResponseInline设置了prefix='applicant',那所有内联字段都要改成applicant-0-...格式。 - 索引不连续:内联表单的索引必须从0开始连续递增,不能跳号(比如不能直接用
jobresponse-1-...而跳过0)。 - 必填字段遗漏:如果
JobResponse有必填字段,POST数据里必须全部包含,否则表单验证会失败。 - 权限问题:测试用的用户必须同时拥有
JobOffer和JobResponse的添加/编辑权限。
内容的提问来源于stack exchange,提问作者AntoineLB
相关产品推荐
相关产品推荐

