我有一个视图,需要显示有关特定模型实例的信息,因此我使用 DetailView
。 我还需要该视图处理常规表单(不是模型表单),在GET
上显示表单并在POST
上验证它。 为此,我尝试使用 FormView
,但两种视图类的组合无法工作:
class FooView(FormView, DetailView):
# configs here
在GET
中(为了简化问题,我只展示与GET
相关的问题,因为POST
有一个不同的问题),它无法工作,因为表单从未被添加到上下文中。原因与该类的方法解析顺序有关:
>>> inspect.getmro(FooView)
(FooView,
django.views.generic.edit.FormView,
django.views.generic.detail.DetailView,
django.views.generic.detail.SingleObjectTemplateResponseMixin,
django.views.generic.base.TemplateResponseMixin,
django.views.generic.edit.BaseFormView,
django.views.generic.edit.FormMixin,
django.views.generic.detail.BaseDetailView,
django.views.generic.detail.SingleObjectMixin,
django.views.generic.base.ContextMixin,
django.views.generic.edit.ProcessFormView,
django.views.generic.base.View,
object)
在请求中,Django需要获取表单并将其添加到上下文中。这发生在ProcessFormView.get
方法中:
def get(self, request, *args, **kwargs):
"""
Handles GET requests and instantiates a blank version of the form.
"""
form_class = self.get_form_class()
form = self.get_form(form_class)
return self.render_to_response(self.get_context_data(form=form))
然而,与定义了get
的MRO中的第一个类是BaseDetailView
:
def get(self, request, *args, **kwargs):
self.object = self.get_object()
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
正如您所看到的,BaseDetailView.get
从未调用 super
,因此永远不会调用 ProcessFormView.get
,因此表单不会添加到上下文中。可以通过创建 Mixin 视图来解决此问题,在其中处理所有这些关于 GET
和 POST
的细节,但我认为这不是一个干净的解决方案。
我的问题是:是否有一种方式可以在 Django 的默认 CBV 实现中实现我想要的功能而不创建任何 Mixin?