2

我使用 Djangorender_to_response返回一个 XML 文档。此特定 XML 文档适用于基于 Flash 的图表库。该库要求 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)
4

3 回答 3

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)
于 2009-09-14T21:13:17.767 回答
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 预先添加到特定响应中。

于 2009-09-14T21:38:59.150 回答
0

最简单的事情可能是将 Emacs 配置为不删除 BOM。

但是 render_to_response 并不是一个复杂的函数。基本上是:

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

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

于 2009-09-14T21:09:49.003 回答