2009-09-14 18 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到特定的反應做​​。