У меня есть представление, где мне нужно отображать информацию об определенном экземпляре модели, поэтому я использую 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))
Однако первый класс с MRO, который имеет GET
, является 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
можно позаботиться, однако я не считаю, что это чистое решение.
Мой вопрос: есть ли способ выполнить то, что я хочу, с реализацией CBV по умолчанию Django без создания каких-либо миксинов?