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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 08:03:02