我使用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)
有帮助吗?

解决方案

你并没有真正谈论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)

其他提示

此解决方案基于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添加到特定的响应中。

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

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top