Django FormView使用dispatch时表单无效报POST方法不允许如何处理
问题根因
- 核心错误触发逻辑:你在
dispatch方法中直接将当前请求(无论GET还是POST)传入了仅支持GET方法的TestViewSetlist接口,当表单校验不通过触发POST请求重走流程时,TestViewSet会返回POST方法不允许的错误响应,此时你拿到的self.data是错误报文而非预期的用户数据,后续读取username字段自然触发KeyError。 - 次要问题:
get_context_data中调用父类时误写为CredentialsView,而非当前类TestViewform_valid方法本身就是表单校验通过后才会执行的钩子,内部不需要再重复调用form.is_valid()
修复方案
- 不要在
dispatch中跨视图调用拿数据,两种最优实现选择:- 若
TestViewSet的用户数据查询逻辑可复用,直接将该逻辑抽为公共方法,两个视图共同调用即可,避免内部HTTP请求的性能损耗 - 若必须调用
TestViewSet接口,手动构造GET请求传入,而非直接使用当前请求
- 若
- 上下文数据的初始化统一放在
get_context_data方法中,不要在dispatch中处理视图专属的上下文逻辑
修复后代码示例
class TestView(LoginRequiredMixin, FormView): form_class = TestForm template_name = 'test.html' def get_user_data(self): # 方式1:直接复用数据查询逻辑(推荐) # return User.objects.filter(id=self.request.user.id).values('username', 'firstname', 'lastname').first() # 方式2:必须调用ViewSet时手动构造GET请求 from rest_framework.test import APIRequestFactory factory = APIRequestFactory() request = factory.get('/fake-path-to-test-viewset/') request.user = self.request.user return TestViewSet.as_view({'get': 'list'})(request).data def get_context_data(self, **kwargs): # 修复父类调用错误 context = super(TestView, self).get_context_data(**kwargs) if self.request.user.is_authenticated: data = self.get_user_data() context['username'] = data['username'] context['firstname'] = data['firstname'] context['lastname'] = data['lastname'] return context def form_valid(self, form): password = form.cleaned_data['password'] # 去掉重复的is_valid校验 return self.query_api(password)
内容的提问来源于stack exchange,提问作者Aditya Singh
相关产品推荐
相关产品推荐

