MikiBelavista
MikiBelavista

Reputation: 2738

Why do we extend HTTPResponse in Django?

I am looking at django-jquery-file-upload

This is response file

MIMEANY = '*/*'
MIMEJSON = 'application/json'
MIMETEXT = 'text/plain'


def response_mimetype(request):
    """response_mimetype -- Return a proper response mimetype, accordingly to
    what the client accepts, as available in the `HTTP_ACCEPT` header.

    request -- a HttpRequest instance.

    """
    can_json = MIMEJSON in request.META['HTTP_ACCEPT']
    can_json |= MIMEANY in request.META['HTTP_ACCEPT']
    return MIMEJSON if can_json else MIMETEXT


class JSONResponse(HttpResponse):
    """JSONResponse -- Extends HTTPResponse to handle JSON format response.

    This response can be used in any view that should return a json stream of
    data.

    Usage:

        def a_iew(request):
            content = {'key': 'value'}
            return JSONResponse(content, mimetype=response_mimetype(request))

    """
    def __init__(self, obj='', json_opts=None, mimetype=MIMEJSON, *args, **kwargs):
        json_opts = json_opts if isinstance(json_opts, dict) else {}
        content = json.dumps(obj, **json_opts)
        super(JSONResponse, self).__init__(content, mimetype, *args, **kwargs)

I do not understand how form_valid(views) is constructed.

def form_valid(self, form):
    self.object = form.save()
    files = [serialize(self.object)]
    data = {'files': files}
    response = JSONResponse(data, mimetype=response_mimetype(self.request))
    response['Content-Disposition'] = 'inline; filename=files.json'
    return response

What is the benefit of using JSON response over HTTPResponse?

Upvotes: 0

Views: 505

Answers (2)

kta
kta

Reputation: 20110

From django docs

If you find yourself needing a response class that Django doesn’t provide, you can create it with the help of http.HTTPStatus. For example:

from http import HTTPStatus 
from django.http import HttpResponse

class HttpResponseNoContent(HttpResponse):
    status_code = HTTPStatus.NO_CONTENT

Upvotes: 1

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476803

Well a JSONResponse is in fact a HTTPResponse. We only add some default functionality for programmer convenience, and to make it harder to make errors.

class JSONResponse(HttpResponse):

    # ...

    def __init__(self, obj='', json_opts=None, mimetype=MIMEJSON, *args, **kwargs):
        json_opts = json_opts if isinstance(json_opts, dict) else {}
        content = json.dumps(obj, **json_opts)
        super(JSONResponse, self).__init__(content, mimetype, *args, **kwargs)

The JSON response basically does two things:

  1. it sets the mimetype by default to application/json such that if you do not provide it yourself, that is the MIME-type, and thus the browser (or other service that consumes the response), knows that this is a JSON response;
  2. it automatically dumps Pyhon objects in a JSON-string (with json.dumps(..)). So instead of passing a JSON stream, you can pass a dictionary, and the JSONResponse will make sure it generates a valid JSON stream.

It also allows to pass specific parameters to this dump (the json_opts) to alter the dumping process a bit (for example dumping non-Vanilla Python objects).

It also makes it easier to add certain logic to all JSON responses. If for example later there is a JSON-2.0 standard, then we can rewrite the JSONResponse logic, and all JSONResponses will use the new logic, instead of patching all occurrences in an ad hoc fashion.

But for a browser, there is no difference at all, since it only sees a HTTP response, with some values filled in. Whether these are filled in by the application programmer, or the Django library makes no difference.

JSON, is the JavaScript Object Notation and is a popular format (like for example XML) to transfer data between applications. JavaScript, Python, Haskell, Java, etc. all have ways to encode and decode JSON. As a result it is typically used to transfer data between systems written in different languages (for example a browser runs JavaScript, and a Django webserver runs with Python).

In Django there is a lot of code that deals with programmer convenience. Take for example the FormView: it will make sure that the programmer does not have to initialize a Form itself, etc. This results in shorter and more elegant code, but also in less errors (since common parts are encapsulated in this class).

Upvotes: 1

Related Questions