У меня есть представление, где мне нужно отображать информацию об определенном экземпляре модели, поэтому я использую DetailView
. Мне также нужен тот же вид для обработки обычной формы (а не образцовой формы), отображающей форму на GET
и проверяя ее на POST
. Чтобы сделать это, я пытаюсь использовать FormView
однако сочетание обоих зрения clases не работает:Django comb DetailView и 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)
В запросе, Джанго должен получить форму и добавить его в контекст. Это происходит в 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 без создания каких-либо миксинов?
Почему вы не хотите использовать микшины? https://docs.djangoproject.com/en/dev/topics/class-based-views/mixins/#using-formmixin-with-detailview –
Это похоже на достаточно простую задачу, с которой должен справиться встроенный CBV. – miki725