Mam widok, w którym muszę wyświetlić informacje o określonym wystąpieniu modelu, dlatego używam DetailView
. Też potrzebuję tego samego widoku, aby obsłużyć zwykły formularz (nie formularz modelu), oba wyświetlając formularz na GET
i potwierdzając go na POST
. Aby to zrobić, próbuję użyć FormView
jednak połączenie obu widoków clases nie działa:Django łączą DetailView i FormView
class FooView(FormView, DetailView):
# configs here
W GET
(dla uproszczenia kwestii pokażę tylko problem z GET
od POST
ma inny problem), nie działa, ponieważ formularz nigdy nie zostanie dodany do kontekstu. Powodem ma do czynienia z celem rezolucji metoda dla tej klasy:
>>> 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)
w żądaniu, Django ma dostać formularz i dodać go do kontekstu. Co dzieje się w 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))
Jednak pierwsza klasa z MRO, który ma get
zdefiniowany jest 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)
Jak widać BaseDetailView.get
nigdy nazywa super
stąd ProcessFormView.get
nigdy nie zostanie wywołana stąd formularz nie zostanie dodany do kontekstu. Można to naprawić, tworząc widok mixin, w którym wszystkie te niuanse mogą być zajęte, jednak nie uważam, że jest to czyste rozwiązanie.
Moje pytanie: czy istnieje sposób na osiągnięcie tego, co chcę z domyślną implementacją CBV Django bez tworzenia żadnych miksów?
Dlaczego nie chcesz używać miksów? https://docs.djangoproject.com/en/dev/topics/class-based-views/mixins/#using-formmixin-with-detailview –
Wydaje się, że jest to dość proste zadanie, które powinna obsłużyć wbudowana funkcja CBV. – miki725