2009-09-14 17 views
2

我使用Django的render_to_response来返回XML文档。这个特定的XML文档是用于基于闪存的图表库。该库要求XML文档以BOM(字节顺序标记)开始。我该如何让Django将BOM用于响应?将BOM添加到来自Django的XML响应

它可以将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) 

回答

2

由于UTF-8没有物料清单,因此您不是在讨论物料清单(字节顺序标记)。在您的示例代码中,库预期文本会因为某些莫名其妙的原因而预留3个垃圾字节。

你的代码几乎是正确的,但是你必须在字节的前面加上字节,而不是字符。试试这个:

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) 
+0

我会想象它*是* UTF-8我们正在谈论。一些(通常是微软派生的)软件喜欢将BOM放在UTF-8中,尽管它们毫无意义且有害。一个XML阅读器需要一个,但它破碎了,根本不是一个XML阅读器。 – bobince 2009-09-14 21:16:53

+0

UTF-8中没有BOM之类的东西,因为UTF-8没有字节顺序。如果某些软件依赖于文件中存在的随机垃圾字节,则情况会有所不同。 – 2009-09-14 21:18:57

+0

@Vebjorn:我已经更新了答案以反映您编辑的问题。你的代码已经几乎正确了。 – 2009-09-14 21:23:01

0

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

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

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

您可以很容易地调用render_to_string并预先配置BOM。

1

该解决方案,基于以前的版本约翰·米利金的回答,比我接受了一个更加复杂,但我在这里,包括它的完整性。首先,定义一个中间件类:

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 

现在,你可以以预先考虑BOM到特定的反应做​​。