Django测试中如何获取self.client.post()创建对象的pk?
如何获取Django测试中POST请求创建对象的PK?
你的问题很典型——Django测试客户端返回的response是一个HTTP响应对象,它本身并没有pk属性,因为它代表的是服务器返回的响应,而不是你刚创建的模型实例。下面是几种可靠的方法来获取这个PK:
方法1:通过数据库查询获取对象(推荐)
最直接且稳定的方式,是根据你提交的表单数据,从数据库中查询刚创建的对象。测试环境是隔离的,你可以放心使用提交的唯一标识字段来精准匹配:
修改你的测试代码如下:
def test_CreateEmployeeProfileView_redirect_on_success(self): # 提交POST请求 response = self.client.post( reverse('service:create_employee_profile'), { 'first_name': 'Test', 'middile_name': 'Testy', 'last_name': 'Testman', 'employee_choices': 'E', } ) # 查询刚创建的员工档案对象 created_profile = EmployeeProfile.objects.get( first_name='Test', last_name='Testman', employee_choices='E' ) # 断言重定向到正确的详情页 self.assertRedirects( response, expected_url=reverse('service:customer_employee_profile_detail', kwargs={'pk': created_profile.pk}), status_code=302, target_status_code=200, )
提示:如果担心字段重复,可以添加更多筛选条件,确保查询结果唯一。
方法2:解析重定向URL中的PK(备选)
如果你的视图在重定向时已经把PK包含在URL路径里,也可以从response.url中提取PK。不过这种方法依赖URL结构,一旦URL规则修改,测试就会失效,所以仅作为备选:
def test_CreateEmployeeProfileView_redirect_on_success(self): response = self.client.post(...) # 根据你的URL结构调整索引,比如URL是 /profile/123/ 就取倒数第二个元素 pk = response.url.split('/')[-2] self.assertRedirects( response, expected_url=reverse('service:customer_employee_profile_detail', kwargs={'pk': pk}), status_code=302, target_status_code=200, )
方法3:从响应上下文获取(仅适用于非重定向场景)
如果你的创建视图成功后是直接渲染页面而非重定向(比如使用CreateView且未设置success_url),那么response.context中会包含刚创建的对象,通常存储在object或自定义的context_object_name键下:
created_profile = response.context['object'] pk = created_profile.pk
不过你的场景是重定向,所以这个方法不适用。
总结来说,方法1是最值得推荐的方案,它直接从数据源获取对象,不受URL结构或视图实现细节的影响,测试稳定性最高。
内容的提问来源于stack exchange,提问作者Carl Brubaker
相关产品推荐
相关产品推荐

