我使用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)
答案 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。