将BOM添加到Django的XML响应中

时间:2009-09-14 21:03:31

标签: xml django byte-order-mark

我使用Django的render_to_response来返回XML文档。此特定XML文档适用于基于闪存的图表库。该库要求XML文档以BOM(字节顺序标记)开头。如何让Django将BOM预先设置为响应?

它可以将BOM插入到模板中,但这很不方便,因为Emacs每次编辑文件时都会将其删除。

我尝试按如下方式重写render_to_response,但由于BOM采用UTF-8编码而失败:

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)

3 个答案:

答案 0 :(得分:2)

你并没有真正谈论BOM(字节顺序标记),因为UTF-8没有BOM。从您的示例代码中,库期望文本前面有3个垃圾字节,这是出于某些无法理解的原因。

您的代码几乎是正确的,但您必须将字节前缀为 bytes ,而不是字符。试试这个:

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)

答案 1 :(得分:1)

此解决方案基于John Millikin先前版本的答案,比我接受的解决方案更复杂,但我将其包含在此处是为了完整性。首先,定义一个中间件类:

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

在您的设置中将其名称添加到MIDDLEWARE_CLASSES。然后重新定义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

现在,您可以执行render_to_response("foo.xml", mimetype="text/xml", bom=True)以便将BOM添加到特定响应中。

答案 2 :(得分:0)

最简单的方法可能是配置Emacs不要删除BOM。

但render_to_response不是一个复杂的功能。基本上是这样的:

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

您可以轻松调用render_to_string并添加BOM。