Prepare BOM for Django XML Response

I am using Django render_to_response

to return an XML document. This particular XML document is for the flash diagram library. The library requires the XML document to start with a BOM (byte byte marker). How can I make Django prefix the BOM for the response?

It works to insert the BOM into the template, but it's inconvenient because Emacs removes it every time I edit the file.

I tried to rewrite render_to_response

as follows, but it fails as the BOM is UTF-8 encoded:

def render_to_response(*args, **kwargs):
    bom = kwargs.pop('bom', False)
    httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
    s = django.template.loader.render_to_string(*args, **kwargs)
    if bom:
        s = u'\xef\xbb\xbf' + s
    return HttpResponse(s, **httpresponse_kwargs)

      

+2


source to share


3 answers


You are not really talking about BOM (byte) as UTF-8 has no BOM. From your example code, the library expects there to be 3 bytes of garbage in the text, preceded by some unexplained reason.

Your code is almost correct, but you have to add bytes as bytes, not characters. Try the following:



def render_to_response(*args, **kwargs):
    bom = kwargs.pop('bom', False)
    httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
    s = django.template.loader.render_to_string(*args, **kwargs)
    if bom:
        s = '\xef\xbb\xbf' + s.encode("utf-8")
    return HttpResponse(s, **httpresponse_kwargs)

      

+2


source


This solution, based on a previous version of John Millikin's answer, is more complex than the one I accepted, but I am including it here for completeness. First, define your middleware class:

class AddBOMMiddleware(object):
    def process_response(self, request, response):
        import codecs
        if getattr(response, 'bom', False):
            response.content = codecs.BOM_UTF8 + response.content
        return response

      

Add your name to MIDDLEWARE_CLASSES to your settings. Then override render_to_response

:



def render_to_response(*args, **kwargs):
    bom = kwargs.pop('bom', False)
    httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
    rendered = django.template.loader.render_to_string(*args, **kwargs)
    response = django.http.HttpResponse(rendered, **httpresponse_kwargs)
    if bom:
        response.bom = True
    return response

      

Now you can do render_to_response("foo.xml", mimetype="text/xml", bom=True)

to add a BOM to a specific answer.

+1


source


The simplest thing might be to configure Emacs to not remove the spec.

But render_to_response is not a complex function. These are basically:

def render_to_response(*args, **kwargs):
    return HttpResponse(loader.render_to_string(*args, **kwargs))

      

You can call render_to_string easily and add a BOM.

0


source







All Articles