我有一个视图,我需要在其中显示有关某个模型实例的信息,因此我使用DetailView
. 我还需要相同的视图来处理常规表单(不是模型表单),在 上显示GET
和验证表单POST
。为此,我尝试使用 aFormView
但是两个视图类的组合不起作用:
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
可以处理,但我不认为这是一个干净的解决方案。
我的问题:有没有什么方法可以在不创建任何 mixin 的情况下使用 Django 的默认 CBV 实现来完成我想要的?