使用Django RequestFactory测试视图时出现TypeError参数缺失报错
问题:使用Django RequestFactory测试视图时提示缺少question_id参数
我在用Django的RequestFactory测试PostedQuestionPage视图的上下文时,运行测试出现了如下报错:
File "C:\Users\..\django\test\testcases.py", line 1201, in setUpClass cls.setUpTestData() Fi..\posts\test\test_views.py", line 334, in setUpTestData cls.view = PostedQuestionPage.as_view()(request) File "C:\..\django\views\generic\base.py", line 70, in view return self.dispatch(request, *args, **kwargs) File "C:\..\django\views\generic\base.py", line 98, in dispatch return handler(request, *args, **kwargs) TypeError: get() missing 1 required positional argument: 'question_id'
我已通过reverse("posts:question", kwargs={'question_id': 1})传入question_id参数,却仍触发该错误,相关代码如下:
test_views.py
class TestQuestionIPAddressHit(TestCase): '''Verify that a page hit is recorded from a user of a given IP address on a posted question.''' @classmethod def setUpTestData(cls): user_author = get_user_model().objects.create_user("ItsNotYou") user_me = get_user_model().objects.create_user("ItsMe") author_profile = Profile.objects.create(user=user_author) user_me = Profile.objects.create(user=user_me) question = Question.objects.create( title="Blah blahhhhhhhhh blahhh I'm bord blah blah zzzzzzzzzzzzz", body="This is zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz...zzzzz", profile=author_profile ) authenticated_user = user_me.user request = RequestFactory().get( reverse("posts:question", kwargs={"question_id": 1}), headers={ "REMOTE_ADDR": "IP Address here" } ) request.user = authenticated_user cls.view = PostedQuestionPage.as_view()(request)
views.py
class PostedQuestionPage(Page): template_name = "posts/question.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['answer_form'] = AnswerForm return context def get(self, request, question_id): context = self.get_context_data() question = get_object_or_404(Question, id=question_id) if question.profile.user != request.user and not question.visible: raise Http404 context |= { 'question': question, 'answer_count': question.answers.count() } return self.render_to_response(context)
urls.py
posts_patterns = ([ path("", pv.QuestionListingPage.as_view(), name="main"), re_path(r"questions/ask/?$", pv.AskQuestionPage.as_view(), name="ask"), re_path(r"questions/(?P<question_id>\d+)/edit/?$", pv.EditQuestionPage.as_view(), name="edit"), re_path(r"questions/(?P<question_id>\d+)/edit/answers/(?P<answer_id>\d+)/?$", pv.EditPostedAnswerPage.as_view(), name="answer_edit"), re_path(r"questions/(?P<question_id>\d+)/?$", pv.PostedQuestionPage.as_view(), name="question"), re_path(r"questions/tagged/(?P<tags>[0-9a-zA-Z\.\-#]+(?:\+[0-9a-zA-Z\.\-#]+)*)$", pv.TaggedSearchResultsPage.as_view(), name="tagged"), re_path(r"questions/tagged/$", pv.SearchTaggedRedirect.as_view(), name="tagged_redirect"), re_path(r"questions/search/$", pv.SearchMenuPage.as_view(), name="search_menu"), re_path(r"questions/search$", pv.SearchResultsPage.as_view(), name="search_results"), re_path(r"questions/?$", pv.AllQuestionsPage.as_view(), name="main_paginated"), ])
解决方法
核心原因
RequestFactory仅负责构造请求对象,不会像Django路由系统那样自动解析URL中的参数并传递给视图的处理方法。你直接调用视图时,没有把question_id作为参数传入,导致get()方法触发参数缺失错误。
方案一:手动传入路由参数
修改测试代码中调用视图的部分,显式传入question_id参数,建议使用创建的question实例的id而非硬编码1,避免数据不一致:
# 替换原cls.view = ...这一行 cls.view = PostedQuestionPage.as_view()(request, question_id=question.id)
方案二:改用Django测试客户端(更推荐)
使用Django内置的Client类来模拟真实请求,它会自动处理路由参数解析,更贴近实际运行场景:
# 替换RequestFactory相关代码 from django.test import Client @classmethod def setUpTestData(cls): # ... 其他创建数据的代码保持不变 ... authenticated_user = user_me # 注意:这里需要修正原代码的变量覆盖问题 client = Client() client.force_login(authenticated_user) cls.response = client.get( reverse("posts:question", kwargs={"question_id": question.id}), REMOTE_ADDR="IP Address here" )
额外修正:测试代码中的变量覆盖问题
原test_views.py中user_me = Profile.objects.create(user=user_me)这一行覆盖了之前的User对象user_me,导致后续user_me.user会报错。建议修改为:
# 替换原user_me = Profile.objects.create(...)这一行 profile_me = Profile.objects.create(user=user_me) authenticated_user = user_me # 直接使用原User对象
内容的提问来源于stack exchange,提问作者binny
相关产品推荐
相关产品推荐

