Reputation: 4983
I have the following class for displaying related course module using formsets
class CourseModuleUpdateView(TemplateResponseMixin, View):
template_name = 'courses/manage/module/formset.html'
course = None
def get_formset(self, data=None):
return ModuleFormSet(instance=self.course, data=data)
def dispatch(self, request, *args, **kwargs):
self.course = get_object_or_404(Course,
id=kwargs['pk'],
owner=request.user)
super(CourseModuleUpdateView, self).dispatch(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
formset = self.get_formset()
return self.render_to_response({'course': self.course, 'formset': formset})
Url pattern responsible for this CBV
url(r'^(?P<pk>\d+)/module/$', views.CourseModuleUpdateView.as_view(), name='course_mudule_update')
Issuing a get request I get the following error
Traceback:
File "/home/mtali/.virtualenvs/educa/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
41. response = get_response(request)
File "/home/mtali/.virtualenvs/educa/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
198. "returned None instead." % (callback.__module__, view_name)
Exception Type: ValueError at /courses/4/module/ Exception Value: The view courses.views.CourseModuleUpdateView didn't return an HttpResponse object. It returned None instead.
What is wrong with my code! I am using django 1.11
Upvotes: 0
Views: 171
Reputation: 24897
As per the Django documentation dispatch method should return a HTTP response.
dispatch(request, *args, **kwargs)
The view part of the view – the method that accepts a request argument plus arguments, and returns a HTTP response.
Explanation based on your code.
From the source code of Django View
class,
def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
dispatch method is not only delegates the requested method to the corresponding handler it also returns back the handler response.
i.e., In this line.
return handler(request, *args, **kwargs)
In your case you are invoking super(CourseModuleUpdateView, self).dispatch(request, *args, **kwargs)
in your dispatch
method, this will invoke the superclass's dispatch method(i.e., View
class dispatch method). Since your requested http method is GET
after executing the following line on the dispatch
method
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
handler will be assigned to get
. So in this case it is roughly equivalent to
def dispatch(self, request, *args, **kwargs):
return get(request, *args, **kwargs)
This get
will invoke the get
method in your CourseModuleUpdateView
class
i.e.,
def get(self, request, *args, **kwargs):
formset = self.get_formset()
return self.render_to_response({'course': self.course, 'formset': formset})
Which returns a valid HTTP response.
This response will reach the place where the get
method is called. i.e., Inside View
s dispatch method. And from there it will return the response from where it is invoked i.e., super(CourseModuleUpdateView, self).dispatch(request, *args, **kwargs)
. Since your not returning response that you received from the dispatch
method resulting in
Exception Type: ValueError at /courses/4/module/ Exception Value: The view courses.views.CourseModuleUpdateView didn't return an HttpResponse object. It returned None instead.
Upvotes: 0