如何测试Django中创建对象时重定向到带参数的URL
测试Django CreateBlogPost视图的重定向逻辑
问题背景
我有一个用于创建博客文章的Django视图,预期创建完成后重定向到文章编辑表单,但使用SimpleTestCase的assertRedirects方法测试时未能成功,当前使用pytest-django框架。
原代码
视图代码
from django.views import View from app.models import BlogPost class CreateBlogPost(View): def post(): new_post = BlogPost.objects.create() return redirect(reverse('post_edit'), args=[new_post.id]) class EditBlogPost(View): ...
URL配置
from django.urls import path from app.views import CreateBlogPost urlpatterns = [ path('post', CreateBlogPost.as_view(), name='post_create'), path('post/<int:pk>/edit', EditBlogPost.as_view(), name='post_edit') ]
问题修复与测试方案
1. 先修复视图的代码错误
原CreateBlogPost的post方法存在两个问题:
- 缺少
self和request必填参数 redirect的参数传递错误,reverse的args应该放在reverse函数内部,而非redirect的第二个参数
修正后的视图代码:
from django.views import View from django.shortcuts import redirect, reverse from app.models import BlogPost class CreateBlogPost(View): def post(self, request): new_post = BlogPost.objects.create() # 写法一:使用reverse拼接URL return redirect(reverse('post_edit', args=[new_post.id])) # 写法二:更简洁的Django redirect用法,自动处理reverse # return redirect('post_edit', new_post.id)
2. 编写pytest-django测试用例
需要标记@pytest.mark.django_db以允许测试操作数据库,使用client fixture发送请求并验证重定向:
import pytest from django.urls import reverse from app.models import BlogPost @pytest.mark.django_db def test_create_post_redirects_to_edit(client): # 发送POST请求到创建接口 response = client.post(reverse('post_create')) # 验证响应状态码为302重定向 assert response.status_code == 302 # 获取刚创建的博客文章 new_post = BlogPost.objects.latest('id') # 生成预期的编辑页面URL expected_edit_url = reverse('post_edit', args=[new_post.id]) # 使用Django的assertRedirects验证重定向目标 response.assertRedirects(expected_edit_url, target_status_code=200) # 或者直接检查URL格式(适合不需要精确ID的场景) assert response.url.startswith('/post/') assert response.url.endswith('/edit')
测试失败的常见原因
- 未添加
@pytest.mark.django_db标记,导致无法创建数据库记录 - 视图本身存在参数缺失、URL反转错误等代码问题
assertRedirects参数错误,比如未指定正确的目标状态码(编辑视图返回200)
内容的提问来源于stack exchange,提问作者Matías Santurio
相关产品推荐
相关产品推荐

