【发布时间】:2013-05-31 16:18:23
【问题描述】:
我有一个视图,我需要在其中显示有关某个模型实例的信息,因此我使用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 的所有这些细微差别,但我不认为这是一个干净的解决方案。
我的问题:有没有什么方法可以在不创建任何 mixins 的情况下使用 Django 的默认 CBV 实现来完成我想要的?
【问题讨论】:
-
你为什么不想使用 mixins? docs.djangoproject.com/en/dev/topics/class-based-views/mixins/…
-
这似乎是一个内置 CBV 应该处理的足够简单的任务。
标签: django django-class-based-views