代码之家  ›  专栏  ›  技术社区  ›  Vebjorn Ljosa

从Django将BOM前置到XML响应

  •  2
  • Vebjorn Ljosa  · 技术社区  · 15 年前

    我用Django的 render_to_response 返回XML文档。这个特定的XML文档用于基于flash的图表库。库要求XML文档以BOM(字节顺序标记)开头。如何让Django为响应准备BOM?

    我试图重写 呈现\u对\u响应 如下所示,但由于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 回复  |  直到 15 年前
        1
  •  2
  •   John Millikin    15 年前

    因为UTF-8没有BOM表,所以您并不是在谈论BOM表(字节顺序标记)。从您的示例代码中,由于某种莫名其妙的原因,库希望文本前面有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)
    
        2
  •  1
  •   Vebjorn Ljosa    15 年前

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

    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
    

    将其名称添加到设置中的类中。然后重新定义 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预先添加到特定响应。

        3
  •  0
  •   Ned Batchelder    15 年前

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

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

    您可以很容易地调用render_to_string并在BOM表前面加上前缀。