2
votes

I'm having trouble returning a valid HttpResponse in my ListView (and am getting a ValueError: The view didn't return an HttpResponse object.... I've overridden get because I want to return a JsonResponse:

def get(self, requets, *args, **kwargs):
    queryset = self.get_queryset()
    data = serializers.serialize("json", queryset)
    return JsonResponse(data, status=200, safe=False)

I've checked that queryset and data and the JsonResponse are not None. Changing the return statement doesn't work:

return HttpResponse(json.dumps(data), content_type="application/json", status=200)

Previously, if I ever needed to override get, I would return render(...), which works.

So, why is my HttpResponse or JsonResponse not an acceptable HttpResponse as per the error in this instance? The GET request will be an ajax request, and I do need to provide some sensible json in reply.

Edit: full class

from django.core import serializers
from django.http import JsonResponse
@method_decorator(login_required, name='dispatch')
class AjaxQuestionList(ListView):
    """
    Generic ListView for Question objects. Called by front-end app.
    Requires hash url parameter to identify Survey.
    Intended to be called via ajax. Returns serialized json list of Questions.
    """
    http_method_names = ['get',]

    def dispatch(self, request, *args, **kwargs):
        #allow user to call this View if their Client owns the Survey
        self.survey = get_object_or_404(Survey, hash=self.kwargs['hash'])
        up = get_object_or_404(UserProfile, fk_user=self.request.user)
        self.client = up.fk_client
        if self.survey.fk_client != self.client:
            raise Http404
        super(AjaxQuestionList, self).dispatch(request, *args, **kwargs)

    def get_queryset(self):
        return Question.objects.filter(fk_survey=self.survey)

    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        data = serializers.serialize("json", queryset)
        return JsonResponse(data, status=200, safe=False)

Traceback:

File "/webapps/escher/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner 39. response = get_response(request)

File "/webapps/escher/lib/python3.5/site-packages/django/core/handlers/base.py" in _legacy_get_response 249. response = self._get_response(request)

File "/webapps/escher/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 /si/survey/123456789/ajax-question-list/ Exception Value: The view myapp.views.survey.AjaxQuestionList didn't return an HttpResponse object. It returned None instead.

From the CBV flattened index I just assumed that render_to_response() was called automatically after get(), rendering whatever HttpResponse get() returned. Am I mistaken?

1
Please show the stack trace, the code you've shown shouldn't produce that errorSayse
Also please show the full view class.Daniel Roseman
Class and traceback added!Escher
Note that render_to_response is called by get(), not after. Since you have override get(), render_to_response will not be called. However, that is ok in your case, because you want to return json instead of rendering a template.Alasdair

1 Answers

5
votes

You need to return the result of super() in your dispatch method.

def dispatch(self, request, *args, **kwargs):
    ... 
    return super(AjaxQuestionList, self).dispatch(request, *args, **kwargs)

Without the return statement, the method returns None so you get the error message.